---
name: assess-quality
description: "Audit a Mendix project against best practices for naming, security, performance, maintainability and architecture, and report a scored result. Use when asked to evaluate project quality, run a pre-go-live health check, or get oriented in an unfamiliar app."
---

# Assess Mendix Project Quality

This skill guides a comprehensive quality assessment of a Mendix project, evaluating it against established best practices across naming, security, performance, maintainability, architecture, and more.

## When to Use This Skill

Use this skill 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

Run the automated linter and report to get a baseline score:

```bash
# connect to the project and build a full catalog (needed for deep analysis)
mxcli -p app.mpr -c "refresh catalog full"

# run the linter (41 rules: MDL, SEC, QUAL, ARCH, design, CONV series)
mxcli lint -p app.mpr

# generate the scored best practices report
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

Use catalog queries to understand the project's shape:

```sql
-- Overview of project size and structure
show structure depth 2

-- Key metrics
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

-- Complexity metrics (McCabe/Sigrid-style)
select qualified_name, cyclomatic_complexity
from CATALOG.microflows
where cyclomatic_complexity > 10
ORDER by cyclomatic_complexity desc

-- Large microflows
select qualified_name, activity_count
from CATALOG.microflows
where activity_count > 15
ORDER by activity_count desc
```

### Step 2b: Architecture & Dependency-Graph Analysis

mxcli models the project as a dependency graph and exposes topological analyses on top of it — god nodes, coupling, cohesion, communities, centrality, cycles, and layering. These answer questions catalog metrics can't: what's central, what's tangled, what belongs together.

**Read [`graph-analysis`](../graph-analysis/SKILL.md) before running graph analysis.** It covers setup (two-step refresh required), all eight use cases (impact assessment, dead code, cohesion, communities, bridges, hotspots, cycles, monolith splits), column schemas, false-positive caveats for dead assets, and a quick-reference table mapping questions to tables.

### Step 3: Manual Review Against Guidelines

After reviewing automated results, assess the following areas manually. The guidelines below are organized by category.

---

## 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:**
1. Call REST service (with custom error handling)
2. On error: check if `$latestHttpResponse` exists
3. If yes: log status code + reason + response content, then rethrow
4. 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)

The catalog includes McCabe cyclomatic complexity metrics aligned with the ISO 25010 maintainability standard used by Sigrid. Use these queries to assess code quality:

```sql
-- Complexity distribution (Sigrid-style)
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

-- Top complex microflows
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

View entities are powerful for specific scenarios but not universal replacements for standard logic:

| 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.

---

## Assessment Report Template

After running the automated tools and performing manual review, produce a report using this structure:

```markdown
# 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]
```

## Sources

This skill incorporates guidelines from:
- **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 on performance optimization
- **Mendix Security Best Practices** — Official Mendix documentation on security configuration
- **DIVD Mendix Findings** — Dutch Institute for Vulnerability Disclosure (entity access misconfigurations)
- **SIG/Sigrid Quality Model** — ISO 25010 maintainability metrics, McCabe complexity benchmarks
