Skip to content

Commit f0707db

Browse files
committed
fix: propagate ELK errors, dedup entity lookup, correct docs
- Propagate ListDomainModels error in describeNanoflowToString - Use shared buildEntityNames() in both microflow and nanoflow ELK paths - Remove Commit/Rollback from BSON mapping disallowed list (allowed by implementation) - Fix example: add missing 'in' keyword in show nanoflows - Fix proposal: CREATE OR REPLACE to CREATE OR MODIFY, correct nanoflow count - Add clarifying comments for best-effort errors, Rollback default, BSON key asymmetry
1 parent 2755f31 commit f0707db

11 files changed

Lines changed: 17 additions & 28 deletions

File tree

.claude/skills/mendix/write-nanoflows.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ Before executing a nanoflow script, verify:
285285
- [ ] Every flow path ends with `return`
286286
- [ ] No code after `return` statements
287287
- [ ] All entity/association names are fully qualified
288-
- [ ] Nanoflow ends with `/` separator
288+
- [ ] Nanoflow ends with `/` separator (statement separator for multi-statement MDL scripts)
289289

290290
## Common Errors
291291

docs/05-mdl-specification/10-bson-mapping.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,8 +1220,6 @@ All other fields — `ObjectCollection`, `Parameters`, `ReturnType`, `AllowedMod
12201220

12211221
Nanoflows run client-side. The following action types are **disallowed** in nanoflows:
12221222

1223-
- `Microflows$CommitAction` — requires database (server-side)
1224-
- `Microflows$RollbackAction` — requires database
12251223
- `Microflows$DownloadFileAction` — requires server response
12261224
- `Microflows$ImportMappingCallAction` — requires server context
12271225
- `Microflows$ExportMappingCallAction` — requires server context

docs/11-proposals/PROPOSAL_nanoflow_support.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Overview
44

55
**Status:** Implemented
6-
**Priority:** High — nanoflows are heavily used (227 across test projects) and CLI parity with microflows is expected.
6+
**Priority:** High — nanoflows are heavily used (223 across test projects) and CLI parity with microflows is expected.
77

88
Full nanoflow feature surface in mxcli: CREATE, DROP, CALL, GRANT/REVOKE, SHOW, SHOW ACCESS, DESCRIBE, DESCRIBE MERMAID, and validation. Supersedes the earlier `show-describe-nanoflows.md` proposal which focused only on DESCRIBE/DROP.
99

@@ -40,7 +40,7 @@ Nanoflows execute client-side (browser or native app). In the Mendix metamodel,
4040
| Command | Description |
4141
|---------|-------------|
4242
| `CREATE NANOFLOW Module.Name(params) RETURNS type BEGIN ... END` | Create a nanoflow with body, parameters, return type |
43-
| `CREATE OR REPLACE NANOFLOW ...` | Create or update existing nanoflow |
43+
| `CREATE OR MODIFY NANOFLOW ...` | Create or update existing nanoflow |
4444
| `DROP NANOFLOW Module.Name` | Delete a nanoflow |
4545
| `CALL NANOFLOW Module.Name(args)` | Call a nanoflow from within a flow body (valid in both microflows and nanoflows) |
4646
| `GRANT EXECUTE ON NANOFLOW Module.Name TO RoleList` | Grant module role access |

examples/create_nanoflow/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ grant execute on nanoflow MyModule.NF_HelloWorld to MyModule.User;
8686
grant execute on nanoflow MyModule.NF_ValidateAndCheck to MyModule.User;
8787
8888
-- Verify: list all nanoflows in the module
89-
show nanoflows MyModule;
89+
show nanoflows in MyModule;
9090
9191
-- Verify: describe a nanoflow
9292
describe nanoflow MyModule.NF_ValidateAndCheck;

mdl/executor/cmd_diff.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ func diffNanoflow(ctx *ExecContext, s *ast.CreateNanoflowStmt) (*DiffResult, err
333333
}
334334

335335
// Try to find existing nanoflow
336+
// Errors treated as "new" to match diffMicroflow and other diff* functions
336337
h, err := getHierarchy(ctx)
337338
if err != nil {
338339
result.IsNew = true

mdl/executor/cmd_microflow_elk.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,9 @@ func microflowELK(ctx *ExecContext, name string) error {
7979
}
8080

8181
// Build entity name lookup
82-
entityNames := make(map[model.ID]string)
83-
domainModels, err := ctx.Backend.ListDomainModels()
82+
entityNames, err := buildEntityNames(ctx, h)
8483
if err != nil {
85-
return mdlerrors.NewBackend("list domain models", err)
86-
}
87-
for _, dm := range domainModels {
88-
modName := h.GetModuleName(dm.ContainerID)
89-
for _, entity := range dm.Entities {
90-
entityNames[entity.ID] = modName + "." + entity.Name
91-
}
84+
return err
9285
}
9386

9487
// Find the microflow

mdl/executor/cmd_microflows_show.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,10 @@ func describeNanoflowToString(ctx *ExecContext, name ast.QualifiedName) (string,
501501
}
502502

503503
entityNames := make(map[model.ID]string)
504-
domainModels, _ := ctx.Backend.ListDomainModels()
504+
domainModels, err := ctx.Backend.ListDomainModels()
505+
if err != nil {
506+
return "", nil, mdlerrors.NewBackend("list domain models", err)
507+
}
505508
for _, dm := range domainModels {
506509
modName := h.GetModuleName(dm.ContainerID)
507510
for _, entity := range dm.Entities {

mdl/executor/cmd_nanoflow_elk.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
"github.com/mendixlabs/mxcli/mdl/ast"
1010
mdlerrors "github.com/mendixlabs/mxcli/mdl/errors"
11-
"github.com/mendixlabs/mxcli/model"
1211
"github.com/mendixlabs/mxcli/sdk/microflows"
1312
)
1413

@@ -31,16 +30,9 @@ func nanoflowELK(ctx *ExecContext, name string) error {
3130
}
3231

3332
// Build entity name lookup
34-
entityNames := make(map[model.ID]string)
35-
domainModels, err := ctx.Backend.ListDomainModels()
33+
entityNames, err := buildEntityNames(ctx, h)
3634
if err != nil {
37-
return mdlerrors.NewBackend("list domain models", err)
38-
}
39-
for _, dm := range domainModels {
40-
modName := h.GetModuleName(dm.ContainerID)
41-
for _, entity := range dm.Entities {
42-
entityNames[entity.ID] = modName + "." + entity.Name
43-
}
35+
return err
4436
}
4537

4638
// Find the nanoflow

mdl/executor/cmd_nanoflows_create.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ func execCreateNanoflow(ctx *ExecContext, s *ast.CreateNanoflowStmt) error {
201201
}
202202
}
203203

204-
hierarchy, _ := getHierarchy(ctx)
205-
restServices, _ := loadRestServices(ctx)
204+
hierarchy, _ := getHierarchy(ctx) // best-effort: builder works without hierarchy
205+
restServices, _ := loadRestServices(ctx) // best-effort: builder works without REST services
206206

207207
builder := &flowBuilder{
208208
posX: 200,

sdk/mpr/parser_microflow_actions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ func parseJavaScriptActionCallAction(raw map[string]any) *microflows.JavaScriptA
138138
mapping := &microflows.JavaScriptActionParameterMapping{}
139139
mapping.ID = model.ID(extractBsonID(mMap["$ID"]))
140140
mapping.Parameter = extractString(mMap["Parameter"])
141+
// BSON key is "ParameterValue"; Go struct JSON tag is "value" — intentional asymmetry
141142
if value, ok := mMap["ParameterValue"].(map[string]any); ok {
142143
mapping.Value = parseCodeActionParameterValue(value)
143144
}

0 commit comments

Comments
 (0)