| name | assess-quality |
| description | Assess Mendix Project Quality — automated linting, catalog queries, naming conventions, security, maintainability, performance, and architecture review with scored report |
| compatibility | opencode |
Mendix quality assessor — automated and manual review against established best practices with scored report.
> Guides a comprehensive quality assessment of a Mendix project across naming, security, performance, maintainability, architecture, and more. Combines automated linting and catalog queries with manual guidelines.
Load when:
- A user asks to evaluate the quality of a Mendix project
- Reviewing a project against best practices before go-live
- Performing a health check or audit on an existing application
- Onboarding onto a project and wanting to understand its quality posture
<assessment_workflow>
Step 1: Run Automated Analysis
./mxcli -p app.mpr -c "refresh catalog full"
./mxcli lint -p app.mpr
./mxcli report -p app.mpr --format markdown
The report covers 6 categories with scores: Naming, Security, Quality, Architecture, Performance, Design.
Step 2: Explore Project Structure
show structure depth 2
select module_name, count(*) from CATALOG.entities GROUP by module_name
select module_name, count(*) from CATALOG.microflows GROUP by module_name
select module_name, count(*) from CATALOG.pages GROUP by module_name
select qualified_name, cyclomatic_complexity
from CATALOG.microflows
where cyclomatic_complexity > 10
ORDER by cyclomatic_complexity desc
select qualified_name, activity_count
from CATALOG.microflows
where activity_count > 15
ORDER by activity_count desc
Step 3: Manual Review Against Guidelines
After reviewing automated results, assess the following areas manually.
</assessment_workflow>
<quality_guidelines_reference>
A. Naming Conventions
Enforced by rules: MPR001, CONV001, CONV003, CONV004, CONV005
| Element | Convention | Example |
|---|
| Entities | Singular, PascalCase, no underscores | Customer, OrderLine (not Customers, Order_Line) |
| Attributes | PascalCase | FirstName, OrderDate |
| Boolean attributes | Prefix with Is/Has/Can/Should/Was/Will | IsActive, HasChildren |
| Microflows | Prefix indicating purpose | ACT_Customer_Save, DS_Customer_GetAll |
| Pages | Entity + suffix | Customer_NewEdit, Order_Overview, Product_View |
| Enumerations | Prefix with ENUM_ | ENUM_OrderStatus, ENUM_Gender |
| Snippets | Prefix with SNIPPET_ | SNIPPET_CustomerDetails |
| Java actions | Prefix with JA_ | JA_SendEmail |
Microflow prefix reference (21 recognized prefixes):
| Prefix | Purpose | Layer |
|---|
ACT_ | UI action (button click handler) | UI |
DS_ | Data source for pages/widgets | UI |
NAV_ | Navigation microflow | UI |
LOGIN_ | Login/authentication flow | UI |
SUB_ | Reusable submicroflow | Logic |
VAL_ | Validation logic | Logic |
BCO_ | Before commit handler | Event |
ACO_ | After commit handler | Event |
BCR_ | Before create handler | Event |
ACR_ | After create handler | Event |
BDE_ | Before delete handler | Event |
ADE_ | After delete handler | Event |
BRO_ | Before rollback handler | Event |
ARO_ | After rollback handler | Event |
OCH_ | On-change handler | Event |
SCH_ | Scheduled event | Integration |
IVK_ | Invocable (called by external systems) | Integration |
SE_ | Scheduled event (alternative) | Integration |
DL_ | Deep link handler | Integration |
PWS_ | Published web service | Integration |
ASU_ | After startup microflow | System |
Manual check: Verify that microflow names are descriptive beyond just the prefix. For example, ACT_Customer_Save is better than ACT_Save.
B. Folder Structure
Not automatically enforced (folder hierarchy not fully captured in catalog)
| Convention | What to Check |
|---|
Each module has [objects] and [UI] top-level folders | Open in Studio Pro or check folder data |
ACT_ and DS_ microflows live in the [UI] folder | These are page-related, belong in UI |
Entity-specific microflows grouped in entity subfolders under [objects] | e.g., [objects]/Customer/BCO_Customer_Validate |
| Pages organized by entity or feature | Not scattered randomly |
C. Security
Enforced by rules: SEC001-SEC009, CONV006, CONV007, CONV008, MPR007
C.1 Entity Access
| Guideline | Rule | Priority |
|---|
| All persistent entities must have access rules | SEC001 | Critical |
| Do not grant Create or Delete rights on entity access rules | CONV006 | High |
| All entity access rules should have XPath constraints | CONV007 | High |
| Set default access rights to None | Manual check | High |
| Do not use entity validation rules (use microflow validation instead) | CONV015 | Medium |
| Do not use entity event handlers (use explicit microflow calls) | CONV016 | Medium |
C.2 Role Management
| Guideline | Rule | Priority |
|---|
| 1:1 mapping between module roles and user roles | CONV008 | High |
| Pages in navigation must have allowed roles | MPR007 | High |
| No guest/anonymous access to sensitive data | SEC004 | Critical |
| Strict security mode enabled | SEC005 | High |
| No demo users in production | SEC003 | Critical |
| Password policy >= 8 characters | SEC002 | High |
C.3 DIVD Findings (Common Misconfigurations)
The Dutch Institute for Vulnerability Disclosure (DIVD) found widespread authorization misconfigurations in Mendix apps. Key checks:
| Check | What to Verify |
|---|
| Anonymous user permissions | Anonymous role should have minimal entity access; no access to business data |
| Newly registered user permissions | Default user role should not grant broad data access |
| XPath constraints completeness | Every READ/WRITE access rule on business entities needs XPath constraints |
| Published REST/OData security | All published services require authentication |
| Entity access audit | Run select * from CATALOG.permissions where is_constrained = 0 |
C.4 Additional Security Practices
- Do not store sensitive information (passwords, API keys) in constants (values are visible in version control)
- Sanitize user input to prevent XSS (use
HTMLSanitize() from Community Commons)
- Be cautious with nanoflow security — nanoflows execute client-side and can be inspected
- Use HTTPS for all external integrations
- Validate and
urlEncode() all values used in REST URLs
D. Maintainability
Enforced by rules: QUAL001-QUAL004, CONV009, CONV012, CONV014, MPR002, MPR004, MPR006
| Guideline | Rule/Check | Threshold |
|---|
| Microflow complexity (McCabe) | QUAL001 | Cyclomatic complexity <= 10 |
| Microflow size | CONV009 | Max 15 activities |
| Documentation on public microflows | QUAL002 | All ACT_, DS_, IVK_ should be documented |
| No orphaned/unused elements | QUAL004 | Remove unused microflows, pages, entities |
| No empty microflows | MPR002 | Every microflow should have at least one activity |
| Caption on exclusive splits | CONV012 | All decision points must have captions |
| No "Continue" error handling | CONV014 | Never swallow errors silently |
| ACT_ microflows: thin controllers | CONV010 | Only page activities + submicroflow calls |
Manual checks:
- Don't change activity captions (they should match the default for readability)
- Don't modify imported/marketplace modules (fork or extend instead)
- Generalize repeated snippets — if the same layout appears 3+ times, extract to a snippet
- Remove all Studio Pro warnings (yellow markers)
- Limit use of non-Mendix languages (Java, JavaScript) to what's necessary
E. Performance
Enforced by rules: CONV011, CONV016, CONV017
| Guideline | Rule/Check | Impact |
|---|
| No calculated attributes | CONV017 | Calculated attributes execute on every retrieve |
| No entity event handlers | CONV016 | Event handlers fire on every create/commit/delete, often unnecessarily |
| No commit inside loops | CONV011 | Each commit is a database round-trip; batch instead |
| No Export to Excel widget | Manual | Use CSV export for large datasets |
| Minimize in-use session objects | Manual | Large session caches increase memory pressure |
XPath performance tips:
- Avoid negation in XPath (
not(), !=) — these cannot use indexes efficiently
- Use indexed attributes in XPath constraints
- Prefer
[Assoc/entity/attribute = value] over retrieving + filtering in microflow
- For large datasets, consider using a data source microflow with pagination
Microflow performance tips:
- Use batching for operations on 100+ objects (retrieve in batches of 1000, process, commit batch)
- Avoid deep nesting of microflow calls (call stack overhead)
- Use list operations (
find, filter, head) instead of loops when possible
F. Architecture
Enforced by rules: ARCH001-ARCH003, CONV010, MPR003
| Guideline | Rule/Check | Details |
|---|
| No cross-module direct data access | ARCH001 | Access data through microflows, not direct entity references |
| Data changes through microflows only | ARCH002 | Don't change entities from pages directly |
| Business key on entities | ARCH003 | Persistent entities should have a business key attribute |
| Domain model size | MPR003 | Max 15 persistent entities per module |
| Entity attribute count | DESIGN001 | Max 10 attributes per entity (consider splitting) |
Manual checks:
- Modules should represent bounded contexts (clear responsibilities)
- Avoid circular dependencies between modules
- Use non-persistent entities for view models / DTOs
- Keep page data sources simple — use DS_ microflows for complex data retrieval
G. Error Handling
Enforced by rules: CONV013, CONV014
| Guideline | Details |
|---|
| Default error handling | All microflows should use Stop + Log + Roll back + Show user message |
| Custom error handling on service calls | REST calls, web service calls, and Java actions need custom error handling |
| Never use "Continue" error handling | This silently swallows errors — always handle explicitly |
| Log with context | Include status code, response body, and input parameters in error logs |
| Rethrow after logging | After logging the error details, rethrow so the caller can handle it |
Pattern for REST call error handling:
- Call REST service (with custom error handling)
- On error: check if
$latestHttpResponse exists
- If yes: log status code + reason + response content, then rethrow
- If no: default error handling is sufficient (timeout/connection refused)
H. Connectors (Consumed Services)
| Guideline | Details |
|---|
| Simplify mappings | Remove empty/optional entities from import mappings |
| Tree structure for domain model | Parent entities above children, use inheritance, add comments between sections |
| String attributes: set to Unlimited | Connector strings should not have length limits |
| Remove default value 0 on numbers | Default 0 is confusing for connector data — leave empty |
| Add documentation to model | Document each entity and attribute purpose |
| Use ConnectionDetails entity | Centralize endpoint, username, password, timeout in one entity |
| Use constants for connection settings | Avoid dependency on Encryption module; use constants with empty defaults |
| Operations naming | Follow METHOD_VERSION_OPERATION pattern |
| File structure | Separate connection Details, Operations, Private folders |
| Validate input before urlEncode | Check for empty values before constructing URLs |
I. UI Best Practices
| Guideline | Details |
|---|
| Use SASS, not inline CSS | All styling in _custom-variables.scss or theme files |
| Avoid nested styling rules | Keep CSS flat for maintainability |
No inline style attributes | Use CSS classes instead |
| Consistent page layout | Use layout grids, not absolute positioning |
J. Quality Metrics (SIG/Sigrid Model)
select
case
when cyclomatic_complexity <= 5 then 'Low (1-5)'
when cyclomatic_complexity <= 10 then 'Moderate (6-10)'
when cyclomatic_complexity <= 20 then 'High (11-20)'
else 'Very High (>20)'
end as complexity_band,
count(*) as microflow_count
from CATALOG.microflows
GROUP by complexity_band
select qualified_name, cyclomatic_complexity, activity_count
from CATALOG.microflows
where cyclomatic_complexity > 10
ORDER by cyclomatic_complexity desc
limit 20
Sigrid benchmarks (5-star system):
- 5 stars: 90%+ of microflows have complexity <= 5
- 4 stars: 80%+ of microflows have complexity <= 10
- 3 stars: 70%+ of microflows have complexity <= 15
- Below 3 stars: significant maintainability risk
K. View Entities
| Use Case | Recommendation |
|---|
| Large dataset performance | View entity is recommended when microflow data source is too slow |
| Complex OQL queries | View entity can replace complex microflow logic with loops/filters |
| Flattening data for reports | More efficient than non-persistent entities filled by microflows |
Caution: View entities increase technical complexity and require OQL knowledge. Only use when there is a clear performance or simplification benefit.
</quality_guidelines_reference>
<assessment_report_template>
# Mendix Project Quality Assessment
**Project:** [Name]
**Date:** [Date]
**Assessor:** Claude Code
## Executive Summary
Overall Score: [X]/100 (from `mxcli report`)
| Category | Score | Key Finding |
|----------|-------|-------------|
| Naming | X% | [one-line summary] |
| Security | X% | [one-line summary] |
| Quality | X% | [one-line summary] |
| Architecture | X% | [one-line summary] |
| Performance | X% | [one-line summary] |
| Design | X% | [one-line summary] |
## Project Metrics
| Metric | Value |
|--------|-------|
| Modules | X |
| Entities (persistent) | X |
| Microflows | X |
| Pages | X |
| Avg Complexity | X |
| Max Complexity | X |
## Automated Findings
[Summary of lint violations by category, grouped by severity]
### Critical Issues (must fix)
- [list]
### High Priority (should fix)
- [list]
### Medium Priority (consider fixing)
- [list]
## Manual Review Findings
### Naming Conventions
[Assessment against Section A guidelines]
### Security Posture
[Assessment against Section C guidelines, including DIVD checklist]
### Maintainability
[Assessment against Section D guidelines]
### Performance Risks
[Assessment against Section E guidelines]
### Architecture
[Assessment against Section F guidelines]
### Error Handling
[Assessment against Section G guidelines]
## Recommendations
### Top 5 Actions (Highest Impact)
1. [specific, actionable recommendation]
2. [specific, actionable recommendation]
3. [specific, actionable recommendation]
4. [specific, actionable recommendation]
5. [specific, actionable recommendation]
### Quick Wins (Low Effort, High Value)
- [list of easy fixes]
### Long-term Improvements
- [list of architectural/structural improvements]
</assessment_report_template>
- Conventions.pdf — Squad Apps internal best practices (14 categories, 80+ guidelines)
- CONV001-CONV017 lint rules — Automated checks derived from Conventions.pdf
- MPR001-MPR007, SEC001-SEC009 — Built-in linter rules
- ARCH, DESIGN, QUAL series — Starlark architecture/quality rules
- Mendix Performance Best Practices — Official Mendix documentation
- Mendix Security Best Practices — Official Mendix documentation
- DIVD Mendix Findings — Dutch Institute for Vulnerability Disclosure
- SIG/Sigrid Quality Model — ISO 25010 maintainability metrics, McCabe complexity benchmarks
<output_rules>Output MDL code only in code blocks. Keep explanations concise.</output_rules>