Skip to content

Commit 680e7a9

Browse files
engalarclaude
authored andcommitted
feat: implement syntax feature registry (Phase 1)
Registry core with workflow (12) and security (8) features registered, --json output, hierarchical drill-down, legacy .txt fallback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 58ebd67 commit 680e7a9

6 files changed

Lines changed: 635 additions & 4 deletions

File tree

cmd/mxcli/help.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"sort"
1010
"strings"
1111

12+
"github.com/mendixlabs/mxcli/cmd/mxcli/syntax"
1213
"github.com/spf13/cobra"
1314
)
1415

@@ -192,10 +193,33 @@ Example:
192193
mxcli syntax security
193194
`,
194195
Run: func(cmd *cobra.Command, args []string) {
196+
jsonFlag, _ := cmd.Flags().GetBool("json")
197+
198+
// No args: show full index (JSON) or help (text)
195199
if len(args) == 0 {
200+
if jsonFlag {
201+
syntax.WriteJSON(os.Stdout, syntax.All())
202+
return
203+
}
196204
cmd.Help()
197205
return
198206
}
207+
208+
// Build registry path from args: "workflow user-task" → "workflow.user-task"
209+
path := strings.ToLower(strings.Join(args, "."))
210+
211+
// Check registry first
212+
if syntax.HasPrefix(path) {
213+
features := syntax.ByPrefix(path)
214+
if jsonFlag {
215+
syntax.WriteJSON(os.Stdout, features)
216+
} else {
217+
syntax.WriteText(os.Stdout, features)
218+
}
219+
return
220+
}
221+
222+
// Fall back to legacy topics (first arg only)
199223
topic := strings.ToLower(args[0])
200224
switch topic {
201225
case "keywords", "reserved":
@@ -224,8 +248,6 @@ Example:
224248
showTopicHelp("structure")
225249
case "search":
226250
showTopicHelp("search")
227-
case "security":
228-
showTopicHelp("security")
229251
case "odata":
230252
showTopicHelp("odata")
231253
case "rest", "rest-client", "rest-clients":
@@ -234,8 +256,6 @@ Example:
234256
showTopicHelp("integration")
235257
case "contract", "contracts":
236258
showTopicHelp("integration")
237-
case "workflow", "workflows":
238-
showTopicHelp("workflow")
239259
case "navigation", "nav":
240260
showTopicHelp("navigation")
241261
case "settings", "project-settings":
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package syntax
4+
5+
func init() {
6+
Register(SyntaxFeature{
7+
Path: "security",
8+
Summary: "Application security: roles, access control, demo users",
9+
Keywords: []string{
10+
"security", "access control", "roles", "permissions",
11+
"grant", "revoke", "authentication", "authorization",
12+
},
13+
Syntax: "SHOW PROJECT SECURITY;\nSHOW MODULE ROLES [IN <module>];\nSHOW USER ROLES;\nSHOW SECURITY MATRIX [IN <module>];",
14+
Example: "SHOW PROJECT SECURITY;\nSHOW SECURITY MATRIX IN Shop;",
15+
SeeAlso: []string{"security.module-role", "security.entity-access", "security.user-role"},
16+
})
17+
18+
Register(SyntaxFeature{
19+
Path: "security.module-role",
20+
Summary: "Create and manage module-level security roles",
21+
Keywords: []string{
22+
"module role", "create role", "drop role",
23+
},
24+
Syntax: "CREATE MODULE ROLE <module>.<role> [DESCRIPTION '<text>'];\nDROP MODULE ROLE <module>.<role>;",
25+
Example: "CREATE MODULE ROLE Shop.Admin DESCRIPTION 'Full access';\nCREATE MODULE ROLE Shop.User DESCRIPTION 'Read-only access';",
26+
SeeAlso: []string{"security.user-role", "security.entity-access"},
27+
})
28+
29+
Register(SyntaxFeature{
30+
Path: "security.entity-access",
31+
Summary: "Grant or revoke entity-level access (CRUD, attribute-level, XPath rules)",
32+
Keywords: []string{
33+
"entity access", "grant", "revoke", "read", "write",
34+
"create", "delete", "xpath", "row-level security",
35+
},
36+
Syntax: "GRANT <role> ON <module>.<entity> (<rights>) [WHERE '<xpath>'];\nREVOKE <role> ON <module>.<entity>;\nREVOKE <role> ON <module>.<entity> (<rights>);\n\nRights: CREATE, DELETE, READ *, READ (<attr>,...), WRITE *, WRITE (<attr>,...)",
37+
Example: "GRANT Shop.Admin ON Shop.Customer (CREATE, DELETE, READ *, WRITE *);\nGRANT Shop.User ON Shop.Customer (READ *) WHERE '[Active = true()]';",
38+
SeeAlso: []string{"security.module-role", "security.microflow-access"},
39+
})
40+
41+
Register(SyntaxFeature{
42+
Path: "security.microflow-access",
43+
Summary: "Grant or revoke execution rights on microflows",
44+
Keywords: []string{
45+
"microflow access", "execute", "grant microflow",
46+
"revoke microflow",
47+
},
48+
Syntax: "GRANT EXECUTE ON MICROFLOW <module>.<name> TO <role> [, <role>...];\nREVOKE EXECUTE ON MICROFLOW <module>.<name> FROM <role> [, <role>...];",
49+
Example: "GRANT EXECUTE ON MICROFLOW Shop.ProcessOrder TO Shop.Admin, Shop.User;\nREVOKE EXECUTE ON MICROFLOW Shop.ProcessOrder FROM Shop.User;",
50+
SeeAlso: []string{"security.page-access", "security.entity-access"},
51+
})
52+
53+
Register(SyntaxFeature{
54+
Path: "security.page-access",
55+
Summary: "Grant or revoke view rights on pages",
56+
Keywords: []string{
57+
"page access", "view", "grant page", "revoke page",
58+
},
59+
Syntax: "GRANT VIEW ON PAGE <module>.<name> TO <role> [, <role>...];\nREVOKE VIEW ON PAGE <module>.<name> FROM <role> [, <role>...];",
60+
Example: "GRANT VIEW ON PAGE Shop.OrderOverview TO Shop.Admin, Shop.User;",
61+
SeeAlso: []string{"security.microflow-access", "security.entity-access"},
62+
})
63+
64+
Register(SyntaxFeature{
65+
Path: "security.user-role",
66+
Summary: "Create and manage application-level user roles that bundle module roles",
67+
Keywords: []string{
68+
"user role", "application role", "manage roles",
69+
"add module roles", "remove module roles",
70+
},
71+
Syntax: "CREATE USER ROLE <name> (<role> [, ...]) [MANAGE ALL ROLES];\nALTER USER ROLE <name> ADD MODULE ROLES (<role> [, ...]);\nALTER USER ROLE <name> REMOVE MODULE ROLES (<role> [, ...]);\nDROP USER ROLE <name>;",
72+
Example: "CREATE USER ROLE AppAdmin (Shop.Admin, HR.Admin) MANAGE ALL ROLES;\nALTER USER ROLE AppAdmin ADD MODULE ROLES (Reporting.Viewer);",
73+
SeeAlso: []string{"security.module-role", "security.demo-user"},
74+
})
75+
76+
Register(SyntaxFeature{
77+
Path: "security.project-security",
78+
Summary: "Set project security level and demo user toggle",
79+
Keywords: []string{
80+
"project security", "security level", "prototype",
81+
"production", "off",
82+
},
83+
Syntax: "ALTER PROJECT SECURITY LEVEL OFF|PROTOTYPE|PRODUCTION;\nALTER PROJECT SECURITY DEMO USERS ON|OFF;",
84+
Example: "ALTER PROJECT SECURITY LEVEL PRODUCTION;\nALTER PROJECT SECURITY DEMO USERS OFF;",
85+
SeeAlso: []string{"security.demo-user"},
86+
})
87+
88+
Register(SyntaxFeature{
89+
Path: "security.demo-user",
90+
Summary: "Create and manage demo users for testing",
91+
Keywords: []string{
92+
"demo user", "test user", "demo account",
93+
"password", "login",
94+
},
95+
Syntax: "CREATE DEMO USER '<name>' PASSWORD '<pass>' [ENTITY Module.Entity] (<userrole> [, ...]);\nDROP DEMO USER '<name>';",
96+
Example: "CREATE DEMO USER 'admin' PASSWORD 'Admin1!' (AppAdmin);\nCREATE DEMO USER 'user' PASSWORD 'User1!' (AppUser);",
97+
SeeAlso: []string{"security.user-role", "security.project-security"},
98+
})
99+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package syntax
4+
5+
func init() {
6+
Register(SyntaxFeature{
7+
Path: "workflow",
8+
Summary: "Multi-step business processes with user tasks, decisions, and parallel paths",
9+
Keywords: []string{
10+
"workflow", "business process", "approval", "review",
11+
"user task", "decision", "parallel",
12+
},
13+
Syntax: "CREATE WORKFLOW Module.Name\n PARAMETER $Context: Module.Entity\nBEGIN\n <activities>\nEND WORKFLOW;",
14+
Example: "CREATE WORKFLOW HR.LeaveApproval\n PARAMETER $Context: HR.LeaveRequest\nBEGIN\n USER TASK Review 'Review request'\n PAGE HR.ReviewPage\n OUTCOMES 'Approve' { } 'Reject' { };\nEND WORKFLOW;",
15+
SeeAlso: []string{"workflow.user-task", "workflow.decision", "workflow.parallel-split"},
16+
})
17+
18+
Register(SyntaxFeature{
19+
Path: "workflow.show",
20+
Summary: "List and describe existing workflows",
21+
Keywords: []string{
22+
"list workflows", "show workflows", "describe workflow",
23+
},
24+
Syntax: "SHOW WORKFLOWS;\nSHOW WORKFLOWS IN <module>;\nDESCRIBE WORKFLOW Module.Name;",
25+
Example: "SHOW WORKFLOWS IN HR;\nDESCRIBE WORKFLOW HR.LeaveApproval;",
26+
})
27+
28+
Register(SyntaxFeature{
29+
Path: "workflow.create",
30+
Summary: "Create a new workflow definition with activities and flow",
31+
Keywords: []string{
32+
"create workflow", "new workflow", "define workflow",
33+
"parameter", "overview page", "due date",
34+
},
35+
Syntax: "CREATE [OR MODIFY] WORKFLOW Module.Name\n PARAMETER $Context: Module.Entity\n [OVERVIEW PAGE Module.OverviewPage]\n [DUE DATE '<expression>']\nBEGIN\n <activities>\nEND WORKFLOW;",
36+
Example: "CREATE WORKFLOW Module.ApprovalFlow\n PARAMETER $Context: Module.Request\n OVERVIEW PAGE Module.WF_Overview\nBEGIN\n USER TASK ReviewTask 'Review the request'\n PAGE Module.ReviewPage\n OUTCOMES 'Approve' { } 'Reject' { };\nEND WORKFLOW;",
37+
SeeAlso: []string{"workflow.user-task", "workflow.decision", "workflow.drop"},
38+
})
39+
40+
Register(SyntaxFeature{
41+
Path: "workflow.user-task",
42+
Summary: "User task activity — assigns work to users with outcomes",
43+
Keywords: []string{
44+
"user task", "human task", "assign", "assignee",
45+
"outcomes", "approve", "reject", "page",
46+
},
47+
Syntax: "USER TASK <name> '<caption>'\n [PAGE Module.Page]\n [TARGETING MICROFLOW Module.MF | TARGETING XPATH '<xpath>']\n [ENTITY Module.Entity]\n OUTCOMES '<outcome1>' { <activities> } '<outcome2>' { <activities> };",
48+
Example: "USER TASK ReviewTask 'Review the request'\n PAGE HR.ReviewPage\n TARGETING XPATH '[Module.Employee/Active = true()]'\n OUTCOMES 'Approve' { } 'Reject' { };",
49+
SeeAlso: []string{"workflow.user-task.targeting", "workflow.create"},
50+
})
51+
52+
Register(SyntaxFeature{
53+
Path: "workflow.user-task.targeting",
54+
Summary: "Control who can pick up a user task — microflow or XPath based",
55+
Keywords: []string{
56+
"targeting", "user targeting", "who can execute",
57+
"assignee", "candidate", "xpath", "microflow",
58+
"task assignment", "user filter",
59+
},
60+
Syntax: "TARGETING MICROFLOW Module.MF\nTARGETING XPATH '<xpath-expression>'",
61+
Example: "-- XPath targeting: only active managers\nUSER TASK Approve 'Approve request'\n TARGETING XPATH '[HR.Employee/Role = \"Manager\" and Active = true()]'\n OUTCOMES 'Done' { };\n\n-- Microflow targeting: custom logic\nUSER TASK Approve 'Approve request'\n TARGETING MICROFLOW HR.GetApprovers\n OUTCOMES 'Done' { };",
62+
MinVersion: "9.0.0",
63+
SeeAlso: []string{"workflow.user-task"},
64+
})
65+
66+
Register(SyntaxFeature{
67+
Path: "workflow.decision",
68+
Summary: "Decision activity — conditional branching based on expression outcomes",
69+
Keywords: []string{
70+
"decision", "conditional", "branch", "if", "condition",
71+
"exclusive gateway", "XOR",
72+
},
73+
Syntax: "DECISION ['<caption>'] [COMMENT '<text>']\n OUTCOMES '<outcome>' { <activities> } ...;",
74+
Example: "DECISION 'Check amount'\n OUTCOMES 'Under 1000' { } 'Over 1000' {\n USER TASK ManagerApproval 'Manager must approve'\n OUTCOMES 'OK' { };\n };",
75+
SeeAlso: []string{"workflow.create", "workflow.parallel-split"},
76+
})
77+
78+
Register(SyntaxFeature{
79+
Path: "workflow.parallel-split",
80+
Summary: "Parallel split — execute multiple paths concurrently",
81+
Keywords: []string{
82+
"parallel", "concurrent", "split", "fork", "join",
83+
"parallel gateway", "AND",
84+
},
85+
Syntax: "PARALLEL SPLIT [COMMENT '<text>']\n PATH 1 { <activities> }\n PATH 2 { <activities> };",
86+
Example: "PARALLEL SPLIT\n PATH 1 {\n USER TASK LegalReview 'Legal review'\n OUTCOMES 'Done' { };\n }\n PATH 2 {\n USER TASK TechReview 'Technical review'\n OUTCOMES 'Done' { };\n };",
87+
SeeAlso: []string{"workflow.decision", "workflow.create"},
88+
})
89+
90+
Register(SyntaxFeature{
91+
Path: "workflow.call-microflow",
92+
Summary: "Call a microflow as a workflow activity",
93+
Keywords: []string{
94+
"call microflow", "microflow task", "automated step",
95+
"system task",
96+
},
97+
Syntax: "CALL MICROFLOW Module.MF [COMMENT '<text>']\n [OUTCOMES '<outcome>' { <activities> } ...];",
98+
Example: "CALL MICROFLOW HR.SendNotification\n COMMENT 'Notify manager';",
99+
SeeAlso: []string{"workflow.create", "workflow.call-workflow"},
100+
})
101+
102+
Register(SyntaxFeature{
103+
Path: "workflow.call-workflow",
104+
Summary: "Call a sub-workflow from within a workflow",
105+
Keywords: []string{
106+
"call workflow", "sub-workflow", "nested workflow",
107+
},
108+
Syntax: "CALL WORKFLOW Module.WF [COMMENT '<text>'];",
109+
Example: "CALL WORKFLOW HR.SubApproval COMMENT 'Delegate to sub-process';",
110+
SeeAlso: []string{"workflow.create", "workflow.call-microflow"},
111+
})
112+
113+
Register(SyntaxFeature{
114+
Path: "workflow.drop",
115+
Summary: "Delete a workflow definition",
116+
Keywords: []string{
117+
"drop workflow", "delete workflow", "remove workflow",
118+
},
119+
Syntax: "DROP WORKFLOW Module.Name;",
120+
Example: "DROP WORKFLOW HR.LeaveApproval;",
121+
SeeAlso: []string{"workflow.create"},
122+
})
123+
124+
Register(SyntaxFeature{
125+
Path: "workflow.catalog",
126+
Summary: "Query workflow metadata via catalog tables",
127+
Keywords: []string{
128+
"catalog", "query workflows", "workflow metadata",
129+
"cross-reference", "callers", "callees",
130+
},
131+
Syntax: "REFRESH CATALOG FULL;\nSELECT * FROM CATALOG.WORKFLOWS;\nSHOW CALLERS OF Module.WorkflowName;\nSHOW REFERENCES TO Module.WorkflowName;",
132+
Example: "REFRESH CATALOG FULL;\nSELECT QualifiedName, ActivityCount, UserTaskCount\n FROM CATALOG.WORKFLOWS WHERE UserTaskCount > 0;",
133+
SeeAlso: []string{"workflow.show"},
134+
})
135+
136+
Register(SyntaxFeature{
137+
Path: "workflow.boundary-event",
138+
Summary: "Attach boundary events (timer) to user tasks for timeouts",
139+
Keywords: []string{
140+
"boundary event", "timer", "timeout", "deadline",
141+
"SLA", "escalation",
142+
},
143+
Syntax: "BOUNDARY TIMER ON <task-name> AFTER '<duration>' {\n <activities>\n}",
144+
Example: "BOUNDARY TIMER ON ReviewTask AFTER 'P3D' {\n CALL MICROFLOW Module.Escalate;\n}",
145+
MinVersion: "10.6.0",
146+
SeeAlso: []string{"workflow.user-task"},
147+
})
148+
149+
Register(SyntaxFeature{
150+
Path: "workflow.alter",
151+
Summary: "Modify an existing workflow — change properties, add/remove activities",
152+
Keywords: []string{
153+
"alter workflow", "modify workflow", "update workflow",
154+
"add activity", "drop activity", "replace activity",
155+
},
156+
Syntax: "ALTER WORKFLOW Module.Name SET <property> = <value>;\nALTER WORKFLOW Module.Name INSERT <activity> [BEFORE|AFTER <name>];\nALTER WORKFLOW Module.Name DROP <activity-name>;\nALTER WORKFLOW Module.Name REPLACE <name> WITH <activity>;",
157+
Example: "ALTER WORKFLOW HR.LeaveApproval SET DUE DATE = 'addDays([%CurrentDateTime%], 7)';\nALTER WORKFLOW HR.LeaveApproval INSERT\n CALL MICROFLOW HR.NotifyHR\n AFTER ReviewTask;",
158+
SeeAlso: []string{"workflow.create", "workflow.drop"},
159+
})
160+
}

0 commit comments

Comments
 (0)