You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Run a structured review of the current branch's changes against the CLAUDE.md
4
+
checklist, then check the recurring findings table below for patterns that have
5
+
burned us before.
6
+
7
+
## Steps
8
+
9
+
1. Run `gh pr view` and `gh pr diff` (or `git diff main...HEAD`) to read the change.
10
+
2. Work through the CLAUDE.md "PR / Commit Review Checklist" in full.
11
+
3. Then check every row in the Recurring Findings table below — flag any match.
12
+
4. Report: blockers first, then moderate issues, then minor. Include a concrete fix
13
+
option for every blocker (not just "this is wrong").
14
+
5. After the review: **add a row** to the Recurring Findings table for any new
15
+
pattern not already covered.
16
+
17
+
---
18
+
19
+
## Recurring Findings
20
+
21
+
Patterns caught in real reviews. Each row is a class of mistake worth checking
22
+
proactively. Add a row after every review that surfaces something new.
23
+
24
+
| # | Finding | Category | Canonical fix |
25
+
|---|---------|----------|---------------|
26
+
| 1 | Formatter emits a keyword not present in `MDLParser.g4` → DESCRIBE output won't re-parse (e.g. `RANGE(...)`) | DESCRIBE roundtrip | Grep grammar before assuming a keyword is valid; if construct can't be expressed yet, emit `-- TypeName(field=value) — not yet expressible in MDL`|
27
+
| 2 | Output uses `$currentObject/Attr` prefix — non-idiomatic; Studio Pro uses bare attribute names | Idiomatic output | Verify against a real Studio Pro BSON sample before choosing a prefix convention |
28
+
| 3 | Malformed BSON field (missing key, wrong type) produces silent garbage output (e.g. `RANGE($x, , )`) | Error handling | Default missing numeric fields to `"0"`; or emit `-- malformed <TypeName>` rather than broken MDL |
29
+
| 4 | No DESCRIBE roundtrip test — grammar gap went undetected until human review | Test coverage | Add roundtrip test: format struct → MDL string → parse → confirm no error |
30
+
| 5 | Hardcoded personal path in committed file (e.g. `/c/Users/Ylber.Sadiku/...`) | Docs quality | Use bare commands (`go test ./...`) without absolute paths in any committed doc or skill |
31
+
| 6 | Docs-only PR cites an unmerged PR as a "model example" — cited PR had blockers | Docs quality | Only cite merged, verified PRs; or annotate with known gaps if citing in-flight work |
32
+
| 7 | Skill/doc table references a function that doesn't exist (e.g. `formatActionStatement()` vs `formatAction()`) | Docs quality | Grep function names before writing: `grep -r "func formatA" mdl/executor/`|
33
+
| 8 | "Always X" rule is too absolute for trivial edge cases (e.g. "always write failing test first" for one-char typos) | Docs quality | Soften to "prefer X" or add an exception clause; include the reasoning so readers can judge edge cases |
34
+
35
+
---
36
+
37
+
## After Every Review
38
+
39
+
-[ ] All blockers have a concrete fix option stated.
40
+
-[ ] Recurring Findings table updated with any new pattern.
41
+
-[ ] If docs-only PR: every function name, path, and PR reference verified against
|`DESCRIBE` shows `$var = LIST OPERATION ...;`| Missing parser case |`sdk/mpr/parser_microflow.go` → `parseListOperation()`| Add `case "Microflows$XxxType":` returning the correct struct |
20
+
|`DESCRIBE` shows `$var = ACTION ...;`| Missing formatter case |`mdl/executor/cmd_microflows_format_action.go` → `formatActionStatement()`| Add `case *microflows.XxxAction:` with `fmt.Sprintf` output |
21
+
|`DESCRIBE` shows `$var = LIST OPERATION %T;` (with type name) | Missing formatter case |`mdl/executor/cmd_microflows_format_action.go` → `formatListOperation()`| Add `case *microflows.XxxOperation:` before the `default`|
|`TypeCacheUnknownTypeException` in Studio Pro | Wrong `$Type` storage name in BSON write |`sdk/mpr/writer_microflow.go`| Check the storage name table in CLAUDE.md; verify against `reference/mendixmodellib/reflection-data/`|
24
+
| CE0066 "Entity access is out of date" | MemberAccess added to wrong entity |`sdk/mpr/writer_domainmodel.go`| MemberAccess must only be on the FROM entity (`ParentPointer`), not the TO entity — see CLAUDE.md association semantics |
25
+
| CE0463 "widget definition changed" | Object property structure doesn't match Type PropertyTypes |`sdk/widgets/templates/`| Re-extract template from Studio Pro; see `sdk/widgets/templates/README.md`|
26
+
| Parser returns `nil` for a known BSON type | Unhandled `default` in a `parseXxx()` switch |`sdk/mpr/parser_microflow.go` or `parser_page.go`| Find the switch by grepping for `default: return nil`; add the missing case |
27
+
| MDL check gives "unexpected token" on valid-looking syntax | Grammar missing rule or token |`mdl/grammar/MDLParser.g4` + `MDLLexer.g4`| Add rule/token, run `make grammar`|
28
+
| CE7054 "parameters updated" / CE7067 "does not support body entity" after `SEND REST REQUEST`|`addSendRestRequestAction` emitted wrong BSON: all params as query params, BodyVariable set for JSON bodies |`mdl/executor/cmd_microflows_builder_calls.go` → `addSendRestRequestAction`| Look up operation via `fb.restServices`; route path/query params with `buildRestParameterMappings`; suppress BodyVariable for JSON/TEMPLATE/FILE via `shouldSetBodyVariable`|
29
+
30
+
---
31
+
32
+
## TDD Protocol
33
+
34
+
Always follow this order — never implement before the test exists:
35
+
36
+
```
37
+
Step 1: Write a failing unit test (parser test or formatter test)
38
+
Step 2: Confirm it fails to compile or fails at runtime
39
+
Step 3: Implement the minimum code to make it pass
40
+
Step 4: Run: /c/Users/Ylber.Sadiku/go/go/bin/go test ./mdl/executor/... ./sdk/mpr/...
41
+
Step 5: Add the symptom row to the table above if not already present
42
+
```
43
+
44
+
Parser tests go in `sdk/mpr/parser_<domain>_test.go`.
45
+
Formatter tests go in `mdl/executor/cmd_<domain>_format_<area>_test.go`.
46
+
47
+
---
48
+
49
+
## Issue #212 — Reference Fix (seeding example)
50
+
51
+
**Symptom:**`DESCRIBE MICROFLOW` showed `$var = LIST OPERATION ...;` for
Steps performed: downloads MxBuild → `mx create-project` → `mxcli init` → downloads correct Linux mxcli binary for devcontainer. The result is a ready-to-open project with `.devcontainer/`, AI tooling, and a working `./mxcli` binary.
358
363
364
+
### Slash Command Namespaces
365
+
366
+
Commands in `.claude/commands/` are organised by audience:
367
+
368
+
| Namespace | Folder | Invoked as | Purpose |
369
+
|-----------|--------|------------|---------|
370
+
|`mendix:`|`.claude/commands/mendix/`|`/mendix:lint`| mxcli **user** commands — synced to Mendix projects via `mxcli init`|
371
+
|`mxcli-dev:`|`.claude/commands/mxcli-dev/`|`/mxcli-dev:review`|**Contributor** commands — this repo only, never synced to user projects |
372
+
373
+
Both namespaces are discoverable by typing `/mxcli` in Claude Code. Add new contributor tooling (review workflows, debugging helpers, etc.) under `mxcli-dev/`. Add commands intended for Mendix project users under `mendix/`.
374
+
359
375
### mxcli init
360
376
361
377
`mxcli init` creates a `.claude/` folder with skills, commands, CLAUDE.md, and VS Code MDL extension in a target Mendix project. Source of truth for synced assets:
0 commit comments