Skip to content

Commit a052d10

Browse files
committed
docs: update docs and skills for workflow, calculated attributes, security
- MDL_QUICK_REFERENCE.md: add Workflows section with all activity types - MDL_FEATURE_MATRIX.md: mark workflow SHOW/DESCRIBE/CREATE/DROP/GRANT/REVOKE - docs/language-reference.md: add CALCULATED attribute syntax - Skills: docker-workflow (empty project, port conflicts, runtime copying) - Skills: generate-domain-model (CALCULATED attribute docs) - Skills: manage-security (ENTITY clause for CREATE DEMO USER) - CLAUDE.md: update project status for implemented features
1 parent f7b3edf commit a052d10

9 files changed

Lines changed: 154 additions & 6 deletions

File tree

.claude/skills/mendix/docker-workflow.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ mxcli docker run -p app.mpr --fresh --wait
5050

5151
`docker run` handles everything: downloads MxBuild and runtime (if not cached), initializes the Docker stack (if needed), builds the PAD package, starts the containers, and optionally waits for the runtime to report successful startup.
5252

53+
## Creating an Empty Mendix App
54+
55+
To create a new blank Mendix project for testing (requires mxbuild to be downloaded first):
56+
57+
```bash
58+
# Download mxbuild if not already cached
59+
mxcli setup mxbuild --version 11.6.4
60+
61+
# Create a blank project
62+
mkdir -p /path/to/my-app
63+
~/.mxcli/mxbuild/{version}/modeler/mx create-project --app-name MyApp --output-dir /path/to/my-app
64+
```
65+
66+
The `mx create-project` command creates an MPR v2 project with the standard Mendix module structure. You can then use the Docker workflow to build and run it.
67+
5368
## Step-by-Step Workflow
5469

5570
If you prefer more control, use the individual commands:
@@ -65,13 +80,38 @@ mxcli setup mxbuild -p app.mpr
6580
# Download Mendix runtime matching the project version
6681
mxcli setup mxruntime -p app.mpr
6782

83+
# Or specify version explicitly (without a project)
84+
mxcli setup mxbuild --version 11.6.4
85+
mxcli setup mxruntime --version 11.6.4
86+
6887
# Or preview what would be downloaded
6988
mxcli setup mxbuild -p app.mpr --dry-run
7089
mxcli setup mxruntime -p app.mpr --dry-run
7190
```
7291

7392
MxBuild is cached at `~/.mxcli/mxbuild/{version}/` and the runtime at `~/.mxcli/runtime/{version}/`. Both are reused across builds.
7493

94+
#### Runtime-to-MxBuild Copying (PAD Build Prerequisite)
95+
96+
MxBuild 11.6.3+ expects runtime files (`pad/`, `lib/`, `launcher/`, `agents/`) inside its own `runtime/` directory, but `mxcli setup mxbuild` only downloads the build tools (not the full runtime). If the PAD build fails with `StudioPro.conf.hbs does not exist` or `ClassNotFoundException`, copy the runtime directories into mxbuild:
97+
98+
```bash
99+
VERSION=11.6.4 # replace with your version
100+
101+
# After downloading both mxbuild and mxruntime:
102+
cp -r ~/.mxcli/runtime/$VERSION/runtime/pad ~/.mxcli/mxbuild/$VERSION/runtime/pad
103+
cp -r ~/.mxcli/runtime/$VERSION/runtime/lib ~/.mxcli/mxbuild/$VERSION/runtime/lib
104+
cp -r ~/.mxcli/runtime/$VERSION/runtime/launcher ~/.mxcli/mxbuild/$VERSION/runtime/launcher
105+
cp -r ~/.mxcli/runtime/$VERSION/runtime/agents ~/.mxcli/mxbuild/$VERSION/runtime/agents
106+
```
107+
108+
**Important:** The PAD build output may only include partial runtime bundles (5 jars instead of 354). If the runtime fails to start with `ClassNotFoundException: com.mendix.container.support.EventProcessor`, copy the full runtime into the PAD build output:
109+
110+
```bash
111+
rm -rf /path/to/project/.docker/build/lib/runtime
112+
cp -r ~/.mxcli/runtime/$VERSION/runtime /path/to/project/.docker/build/lib/runtime
113+
```
114+
75115
### 2. Initialize Docker stack (first time only)
76116

77117
```bash
@@ -81,6 +121,16 @@ mxcli docker init -p app.mpr
81121

82122
This creates a `.docker/` directory with Docker Compose configuration for the Mendix app + PostgreSQL.
83123

124+
**Port conflicts:** If default ports (8080/8090/5432) are already in use, check with `ss -tlnp | grep -E '808|809|543'` and use `--port-offset N` to shift all ports:
125+
126+
```bash
127+
# Check which ports are occupied
128+
ss -tlnp | grep -E '808[0-9]|809[0-9]|543[0-9]'
129+
130+
# Use offset to avoid conflicts (e.g., offset 5 → 8085/8095/5437)
131+
mxcli docker init -p app.mpr --port-offset 5
132+
```
133+
84134
### 3. Check project for errors
85135

86136
```bash
@@ -346,6 +396,9 @@ All defaults can be overridden in `.docker/.env`.
346396
| Build fails with version error | Requires Mendix >= 11.6.1 for PAD support |
347397
| No Dockerfile in PAD output | Normal for MxBuild 11.6.3+ — `mxcli docker build` auto-generates one |
348398
| Runtime not found / runtimelauncher.jar missing | Run `mxcli setup mxruntime -p app.mpr` or let `docker build` auto-download |
399+
| `StudioPro.conf.hbs does not exist` | Runtime not linked into mxbuild — see "Runtime-to-MxBuild Copying" above |
400+
| `ClassNotFoundException: EventProcessor` | PAD has partial runtime bundles — copy full runtime into `.docker/build/lib/runtime/` (see above) |
401+
| Port already allocated | Check ports with `ss -tlnp \| grep 808` and use `docker init --port-offset N --force` |
349402
| `' etc/Default' is not a file` | Dockerfile CMD passes config arg — `docker build` patches this automatically |
350403
| `DatabasePassword has no value` | Ensure `RUNTIME_PARAMS_DATABASE*` env vars are in docker-compose.yml — re-run `mxcli docker init --force` |
351404
| `Password should not be empty (debugger)` | Add `RUNTIME_DEBUGGER_PASSWORD` — re-run `mxcli docker init --force` |

.claude/skills/mendix/generate-domain-model.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,29 @@ COMMENT 'Additional documentation';
326326

327327
**Naming Convention**: `{FromEntity}_{ToEntity}` (e.g., `Order_Customer`, `Transaction_Account`)
328328

329+
#### Calculated Attributes
330+
331+
Calculated attributes derive their value from a microflow at runtime. Use `CALCULATED BY Module.Microflow` to specify the calculation microflow.
332+
333+
**IMPORTANT: CALCULATED attributes are only supported on PERSISTENT entities.** Using CALCULATED on non-persistent entities will produce a validation error.
334+
335+
```sql
336+
@Position(100, 100)
337+
CREATE PERSISTENT ENTITY Module.OrderLine (
338+
/** Unit price */
339+
UnitPrice: Decimal NOT NULL,
340+
/** Quantity ordered */
341+
Quantity: Integer NOT NULL,
342+
/** Total price, calculated by microflow */
343+
TotalPrice: Decimal CALCULATED BY Module.CalcTotalPrice
344+
);
345+
```
346+
347+
**Syntax variants:**
348+
- `CALCULATED BY Module.Microflow` — recommended, binds the calculation microflow directly
349+
- `CALCULATED Module.Microflow` — also valid (`BY` keyword is optional)
350+
- `CALCULATED` — bare form, marks as calculated but requires manual microflow binding in Studio Pro
351+
329352
### Data Types
330353

331354
| Type | Example | Description |

.claude/skills/mendix/manage-security.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,18 @@ ALTER PROJECT SECURITY DEMO USERS OFF;
171171
### Demo Users
172172

173173
```sql
174-
-- Create demo user with roles
174+
-- Create demo user (auto-detects entity that generalizes System.User)
175175
CREATE DEMO USER 'demo_admin' PASSWORD 'Admin123!' (Administrator, SuperAdmin);
176176

177+
-- Create demo user with explicit entity
178+
CREATE DEMO USER 'demo_admin' PASSWORD 'Admin123!' ENTITY Administration.Account (Administrator, SuperAdmin);
179+
177180
-- Remove demo user
178181
DROP DEMO USER 'demo_admin';
179182
```
180183

184+
The ENTITY clause specifies which entity (generalizing `System.User`) to use. If omitted, it auto-detects the unique System.User subtype in the project. If multiple subtypes exist, you must specify ENTITY explicitly.
185+
181186
## Starlark Lint Rule APIs
182187

183188
Security data is available in Starlark lint rules (`.star` files):

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,6 @@ grammardoc
5454
*.pptx
5555
# Excluded skills
5656
.claude/skills/mendix/migrate-outsystems.md
57+
58+
# Snap tool binary (used for BSON fixture generation)
59+
snap-bson

CLAUDE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,11 @@ Full syntax tables for all MDL statements (microflows, pages, security, navigati
325325
- Data import from external databases into Mendix app DB (`IMPORT FROM ... INTO ... MAP ...`)
326326
- Database Connector generation from external schema (`SQL <alias> GENERATE CONNECTOR INTO <module>`)
327327
- EXECUTE DATABASE QUERY microflow action (static, dynamic SQL, parameterized, runtime connection override)
328+
- CREATE/DROP WORKFLOW with user tasks, decisions, parallel splits, and other activity types
329+
- CALCULATED BY microflow syntax for calculated attributes
328330

329331
**Not Yet Implemented:**
330-
- 48 of 52 metamodel domains (workflows, REST, etc.)
332+
- 47 of 52 metamodel domains (REST, etc.)
331333
- Delta/change tracking system
332334
- Runtime type reflection
333335

cmd/mxcli/skills/generate-domain-model.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,29 @@ COMMENT 'Additional documentation';
326326

327327
**Naming Convention**: `{FromEntity}_{ToEntity}` (e.g., `Order_Customer`, `Transaction_Account`)
328328

329+
#### Calculated Attributes
330+
331+
Calculated attributes derive their value from a microflow at runtime. Use `CALCULATED BY Module.Microflow` to specify the calculation microflow.
332+
333+
**IMPORTANT: CALCULATED attributes are only supported on PERSISTENT entities.** Using CALCULATED on non-persistent entities will produce a validation error.
334+
335+
```sql
336+
@Position(100, 100)
337+
CREATE PERSISTENT ENTITY Module.OrderLine (
338+
/** Unit price */
339+
UnitPrice: Decimal NOT NULL,
340+
/** Quantity ordered */
341+
Quantity: Integer NOT NULL,
342+
/** Total price, calculated by microflow */
343+
TotalPrice: Decimal CALCULATED BY Module.CalcTotalPrice
344+
);
345+
```
346+
347+
**Syntax variants:**
348+
- `CALCULATED BY Module.Microflow` — recommended, binds the calculation microflow directly
349+
- `CALCULATED Module.Microflow` — also valid (`BY` keyword is optional)
350+
- `CALCULATED` — bare form, marks as calculated but requires manual microflow binding in Studio Pro
351+
329352
### Data Types
330353

331354
| Type | Example | Description |

docs/01-project/MDL_FEATURE_MATRIX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ Document types that exist in Mendix but have no MDL support:
204204
| **JSON transformations** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | JSON structure definitions |
205205
| **Message definitions** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Message definition documents |
206206
| **XML schemas** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Imported XML schema documents |
207-
| **Workflows** | Y | Y | N | N | N | N | N | N | Y | Y | N | N | Y | N | N | Y | N | SHOW/DESCRIBE work; CREATE/DROP not implemented |
207+
| **Workflows** | Y | Y | Y | N | Y | N | N | N | Y | Y | N | N | Y | N | Y | Y | N | SHOW/DESCRIBE/CREATE/DROP/GRANT/REVOKE implemented |
208208
| **Module settings** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Module-level configuration |
209209
| **Image collection** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Image document collections |
210210
| **Icon collection** | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Icon/glyph collections |

docs/01-project/MDL_QUICK_REFERENCE.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,43 @@ Nested folders use `/` separator: `'Parent/Child/Grandchild'`. Missing folders a
208208
| Revoke entity access | `REVOKE Mod.Role ON Mod.Entity;` | |
209209
| Set security level | `ALTER PROJECT SECURITY LEVEL OFF\|PROTOTYPE\|PRODUCTION;` | |
210210
| Toggle demo users | `ALTER PROJECT SECURITY DEMO USERS ON\|OFF;` | |
211-
| Create demo user | `CREATE DEMO USER 'name' PASSWORD 'pass' (UserRole, ...);` | |
211+
| Create demo user | `CREATE DEMO USER 'name' PASSWORD 'pass' [ENTITY Module.Entity] (UserRole, ...);` | |
212212
| Drop demo user | `DROP DEMO USER 'name';` | |
213213

214+
## Workflows
215+
216+
| Statement | Syntax | Notes |
217+
|-----------|--------|-------|
218+
| Show workflows | `SHOW WORKFLOWS [IN Module];` | List all or filter by module |
219+
| Describe workflow | `DESCRIBE WORKFLOW Module.Name;` | Full MDL output |
220+
| Create workflow | `CREATE [OR MODIFY] WORKFLOW Module.Name PARAMETER $Ctx: Module.Entity BEGIN ... END WORKFLOW;` | See activity types below |
221+
| Drop workflow | `DROP WORKFLOW Module.Name;` | |
222+
| Grant workflow access | `GRANT EXECUTE ON WORKFLOW Module.Name TO Mod.Role, ...;` | |
223+
| Revoke workflow access | `REVOKE EXECUTE ON WORKFLOW Module.Name FROM Mod.Role, ...;` | |
224+
225+
**Workflow Activity Types:**
226+
- `USER TASK <name> '<caption>' [PAGE Mod.Page] [TARGETING MICROFLOW Mod.MF] [OUTCOMES '<out>' { } ...];`
227+
- `CALL MICROFLOW Mod.MF [COMMENT '<text>'] [OUTCOMES '<out>' { } ...];`
228+
- `CALL WORKFLOW Mod.WF [COMMENT '<text>'];`
229+
- `DECISION ['<caption>'] OUTCOMES '<out>' { } ...;`
230+
- `PARALLEL SPLIT PATH 1 { } PATH 2 { };`
231+
- `JUMP TO <activity-name>;`
232+
- `WAIT FOR TIMER ['<expr>'];`
233+
- `WAIT FOR NOTIFICATION;`
234+
- `END;`
235+
236+
**Example:**
237+
```sql
238+
CREATE WORKFLOW Module.ApprovalFlow
239+
PARAMETER $Context: Module.Request
240+
OVERVIEW PAGE Module.WorkflowOverview
241+
BEGIN
242+
USER TASK ReviewTask 'Review the request'
243+
PAGE Module.ReviewPage
244+
OUTCOMES 'Approve' { } 'Reject' { };
245+
END WORKFLOW;
246+
```
247+
214248
## Project Structure
215249

216250
| Statement | Syntax | Notes |
@@ -417,6 +451,8 @@ Both double-quote (ANSI SQL) and backtick (MySQL) styles are supported. You can
417451

418452
**Boolean attributes** auto-default to `false` when no `DEFAULT` is specified.
419453

454+
**CALCULATED** marks an attribute as calculated (not stored). Use `CALCULATED BY Module.Microflow` to specify the calculation microflow. Calculated attributes derive their value from a microflow at runtime.
455+
420456
**ButtonStyle** supports all values: `Primary`, `Default`, `Success`, `Danger`, `Warning`, `Info`.
421457

422458
## External SQL Statements

docs/05-mdl-specification/01-language-reference.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ CREATE [OR MODIFY] <entity-type> ENTITY <qualified-name> (
405405
**Attribute Definition:**
406406
```sql
407407
[/** <documentation> */]
408-
<name>: <type> [NOT NULL [ERROR '<message>']] [UNIQUE [ERROR '<message>']] [DEFAULT <value>]
408+
<name>: <type> [NOT NULL [ERROR '<message>']] [UNIQUE [ERROR '<message>']] [DEFAULT <value>] [CALCULATED]
409409
```
410410

411411
**Examples:**
@@ -1084,12 +1084,15 @@ Creates a demo user for development/testing.
10841084

10851085
**Syntax:**
10861086
```sql
1087-
CREATE DEMO USER '<username>' PASSWORD '<password>' (<userrole> [, ...])
1087+
CREATE DEMO USER '<username>' PASSWORD '<password>' [ENTITY <Module.Entity>] (<userrole> [, ...])
10881088
```
10891089

1090+
The optional `ENTITY` clause specifies the entity that generalizes `System.User` (e.g., `Administration.Account`). If omitted, the system auto-detects the unique `System.User` subtype.
1091+
10901092
**Example:**
10911093
```sql
10921094
CREATE DEMO USER 'demo_admin' PASSWORD 'Admin123!' (AppAdmin);
1095+
CREATE DEMO USER 'demo_admin' PASSWORD 'Admin123!' ENTITY Administration.Account (AppAdmin);
10931096
```
10941097

10951098
### DROP DEMO USER

0 commit comments

Comments
 (0)