--- 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 # score only the app's own modules (not Marketplace / platform modules) mxcli report -p app.mpr --modules MyModule,OtherModule --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 describe 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