Skip to content

Commit 965d186

Browse files
akoclaude
andcommitted
feat: add version feature registry with YAML data and Go loader
Implements Phase 1 of the version-aware agent support proposal: - YAML feature definitions for Mendix 9, 10, 11 with min_version/max_version bounds - Registry package (sdk/versions/) with go:embed loader and query methods - Wire SupportsFeature() to check YAML registry first, fallback to hardcoded map Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d8c8eee commit 965d186

File tree

6 files changed

+1034
-0
lines changed

6 files changed

+1034
-0
lines changed

sdk/mpr/version/version.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"fmt"
99
"strconv"
1010
"strings"
11+
12+
"github.com/mendixlabs/mxcli/sdk/versions"
1113
)
1214

1315
// ProjectVersion contains version information for a Mendix project.
@@ -151,7 +153,19 @@ func (v *ProjectVersion) IsSupported() bool {
151153
}
152154

153155
// SupportsFeature checks if a specific feature is available in this version.
156+
// It first checks the YAML-based version registry, falling back to the
157+
// hardcoded featureVersions map for features not yet in the registry.
154158
func (v *ProjectVersion) SupportsFeature(feature Feature) bool {
159+
// Try the YAML registry first via the feature-to-registry mapping.
160+
if mapping, ok := featureRegistry[feature]; ok {
161+
reg, err := versions.Load()
162+
if err == nil {
163+
pv := versions.SemVer{Major: v.MajorVersion, Minor: v.MinorVersion, Patch: v.PatchVersion}
164+
return reg.IsAvailable(mapping.Area, mapping.Name, pv)
165+
}
166+
}
167+
168+
// Fallback to hardcoded map.
155169
minVersion, ok := featureVersions[feature]
156170
if !ok {
157171
return false
@@ -172,13 +186,30 @@ const (
172186
FeaturePortableApp Feature = "PortableApp"
173187
)
174188

189+
// registryMapping maps a Feature constant to its area.name in the YAML registry.
190+
type registryMapping struct {
191+
Area string
192+
Name string
193+
}
194+
195+
// featureRegistry maps Feature constants to their YAML registry keys.
196+
var featureRegistry = map[Feature]registryMapping{
197+
FeatureViewEntities: {Area: "domain_model", Name: "view_entities"},
198+
FeatureAssociationStorage: {Area: "mpr_format", Name: "association_storage"},
199+
FeatureMPRv2: {Area: "mpr_format", Name: "mpr_v2"},
200+
FeatureBusinessEvents: {Area: "integration", Name: "business_events"},
201+
FeatureWorkflows: {Area: "workflows", Name: "basic"},
202+
FeaturePortableApp: {Area: "mpr_format", Name: "portable_app"},
203+
}
204+
175205
// MinVersion represents a minimum version requirement.
176206
type MinVersion struct {
177207
Major int
178208
Minor int
179209
}
180210

181211
// featureVersions maps features to their minimum required versions.
212+
// This is the fallback when the YAML registry is unavailable.
182213
var featureVersions = map[Feature]MinVersion{
183214
FeatureViewEntities: {Major: 10, Minor: 18},
184215
FeatureAssociationStorage: {Major: 11, Minor: 0},

sdk/versions/mendix-10.yaml

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
major: 10
2+
supported_range: "10.0.0..10.24.99"
3+
lts_versions: ["10.24"]
4+
mts_versions: ["10.6", "10.12", "10.18"]
5+
6+
features:
7+
domain_model:
8+
entities:
9+
min_version: "10.0.0"
10+
mdl: "CREATE PERSISTENT ENTITY Module.Name (...)"
11+
non_persistent_entities:
12+
min_version: "10.0.0"
13+
mdl: "CREATE NON-PERSISTENT ENTITY Module.Name (...)"
14+
view_entities:
15+
min_version: "10.18.0"
16+
mdl: "CREATE VIEW ENTITY Module.Name (...) AS SELECT ..."
17+
notes: "OQL stored inline on OqlViewEntitySource in 10.x"
18+
calculated_attributes:
19+
min_version: "10.0.0"
20+
mdl: "CALCULATED BY Module.Microflow"
21+
entity_generalization:
22+
min_version: "10.0.0"
23+
mdl: "EXTENDS Module.ParentEntity"
24+
alter_entity:
25+
min_version: "10.0.0"
26+
mdl: "ALTER ENTITY Module.Name ADD ATTRIBUTE ..."
27+
28+
oql_functions:
29+
basic_select:
30+
min_version: "10.18.0"
31+
mdl: "SELECT, FROM, WHERE, AS, AND, OR, NOT"
32+
aggregate_functions:
33+
min_version: "10.18.0"
34+
mdl: "COUNT, SUM, AVG, MIN, MAX, GROUP BY"
35+
subqueries:
36+
min_version: "10.18.0"
37+
mdl: "Inline subqueries in SELECT and WHERE"
38+
join_types:
39+
min_version: "10.18.0"
40+
mdl: "INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN"
41+
42+
microflows:
43+
basic:
44+
min_version: "10.0.0"
45+
mdl: "CREATE MICROFLOW Module.Name (...) BEGIN ... END"
46+
show_page_with_params:
47+
min_version: "11.0.0"
48+
workaround:
49+
description: "Pass data via a non-persistent entity or microflow parameter"
50+
max_version: "10.99.99"
51+
send_rest_request:
52+
min_version: "10.1.0"
53+
mdl: "SEND REST REQUEST ..."
54+
send_rest_query_params:
55+
min_version: "11.0.0"
56+
notes: "Query parameters in REST requests"
57+
execute_database_query:
58+
min_version: "10.6.0"
59+
mdl: "EXECUTE DATABASE QUERY ..."
60+
execute_database_query_runtime_connection:
61+
min_version: "11.0.0"
62+
notes: "Runtime connection override for database queries"
63+
loop_in_branch:
64+
min_version: "10.0.0"
65+
notes: "LOOP inside IF/ELSE branches"
66+
67+
pages:
68+
basic:
69+
min_version: "10.0.0"
70+
mdl: "CREATE PAGE Module.Name (...) { ... }"
71+
page_parameters:
72+
min_version: "11.0.0"
73+
workaround:
74+
description: "Use non-persistent entity or microflow parameter"
75+
max_version: "10.99.99"
76+
page_variables:
77+
min_version: "11.0.0"
78+
pluggable_widgets:
79+
min_version: "10.0.0"
80+
notes: "Widget templates are version-specific; MPK augmentation handles drift"
81+
design_properties_v3:
82+
min_version: "11.0.0"
83+
notes: "Atlas v3 design properties (Card style, Disable row wrap)"
84+
alter_page:
85+
min_version: "10.0.0"
86+
mdl: "ALTER PAGE Module.Name SET/INSERT/DROP/REPLACE ..."
87+
88+
security:
89+
module_roles:
90+
min_version: "10.0.0"
91+
user_roles:
92+
min_version: "10.0.0"
93+
entity_access:
94+
min_version: "10.0.0"
95+
demo_users:
96+
min_version: "10.0.0"
97+
98+
integration:
99+
rest_client_basic:
100+
min_version: "10.1.0"
101+
mdl: "CREATE REST CLIENT Module.Name ..."
102+
rest_client_query_params:
103+
min_version: "11.0.0"
104+
rest_client_headers:
105+
min_version: "10.4.0"
106+
database_connector_basic:
107+
min_version: "10.6.0"
108+
mdl: "CREATE DATABASE CONNECTION Module.Name ..."
109+
database_connector_execute:
110+
min_version: "10.6.0"
111+
mdl: "EXECUTE DATABASE QUERY in microflows"
112+
notes: "Full BSON format requires 11.0+"
113+
business_events:
114+
min_version: "10.0.0"
115+
mdl: "CREATE BUSINESS EVENT SERVICE Module.Name ..."
116+
odata_client:
117+
min_version: "10.0.0"
118+
119+
workflows:
120+
basic:
121+
min_version: "9.0.0"
122+
mdl: "CREATE WORKFLOW Module.Name ..."
123+
parallel_split:
124+
min_version: "9.0.0"
125+
user_task:
126+
min_version: "9.0.0"
127+
128+
navigation:
129+
profiles:
130+
min_version: "10.0.0"
131+
menu_items:
132+
min_version: "10.0.0"
133+
home_pages:
134+
min_version: "10.0.0"
135+
136+
mpr_format:
137+
mpr_v2:
138+
min_version: "10.18.0"
139+
notes: "MPR metadata + mprcontents/ folder with individual documents"
140+
portable_app:
141+
min_version: "11.6.0"
142+
notes: "New portable app deployment format"
143+
144+
deprecated:
145+
- id: "DEP001"
146+
pattern: "Persistable: false on view entities"
147+
replaced_by: "Persistable: true (auto-set)"
148+
since: "10.18.0"
149+
severity: "info"
150+
151+
upgrade_opportunities:
152+
from_10_to_11:
153+
- feature: "page_parameters"
154+
description: "Replace non-persistent entity parameter passing with direct page parameters"
155+
effort: "low"
156+
- feature: "design_properties_v3"
157+
description: "Atlas v3 design properties available for richer styling"
158+
effort: "low"
159+
- feature: "rest_client_query_params"
160+
description: "REST clients can now define query parameters directly"
161+
effort: "low"
162+
- feature: "database_connector_runtime_connection"
163+
description: "Database queries can override connection at runtime"
164+
effort: "low"
165+
- feature: "association_storage"
166+
description: "New association storage format (automatic on project upgrade)"
167+
effort: "none"

sdk/versions/mendix-11.yaml

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
major: 11
2+
supported_range: "11.0.0..11.99.99"
3+
4+
features:
5+
domain_model:
6+
entities:
7+
min_version: "10.0.0"
8+
mdl: "CREATE PERSISTENT ENTITY Module.Name (...)"
9+
non_persistent_entities:
10+
min_version: "10.0.0"
11+
mdl: "CREATE NON-PERSISTENT ENTITY Module.Name (...)"
12+
view_entities:
13+
min_version: "10.18.0"
14+
mdl: "CREATE VIEW ENTITY Module.Name (...) AS SELECT ..."
15+
calculated_attributes:
16+
min_version: "10.0.0"
17+
mdl: "CALCULATED BY Module.Microflow"
18+
entity_generalization:
19+
min_version: "10.0.0"
20+
mdl: "EXTENDS Module.ParentEntity"
21+
alter_entity:
22+
min_version: "10.0.0"
23+
mdl: "ALTER ENTITY Module.Name ADD ATTRIBUTE ..."
24+
25+
oql_functions:
26+
basic_select:
27+
min_version: "10.18.0"
28+
mdl: "SELECT, FROM, WHERE, AS, AND, OR, NOT"
29+
aggregate_functions:
30+
min_version: "10.18.0"
31+
mdl: "COUNT, SUM, AVG, MIN, MAX, GROUP BY"
32+
subqueries:
33+
min_version: "10.18.0"
34+
mdl: "Inline subqueries in SELECT and WHERE"
35+
join_types:
36+
min_version: "10.18.0"
37+
mdl: "INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN"
38+
39+
microflows:
40+
basic:
41+
min_version: "10.0.0"
42+
mdl: "CREATE MICROFLOW Module.Name (...) BEGIN ... END"
43+
show_page_with_params:
44+
min_version: "11.0.0"
45+
mdl: "SHOW PAGE Module.PageName WITH PARAMS ..."
46+
send_rest_request:
47+
min_version: "10.1.0"
48+
mdl: "SEND REST REQUEST ..."
49+
send_rest_query_params:
50+
min_version: "11.0.0"
51+
mdl: "SEND REST REQUEST with query parameters"
52+
execute_database_query:
53+
min_version: "10.6.0"
54+
mdl: "EXECUTE DATABASE QUERY ..."
55+
execute_database_query_runtime_connection:
56+
min_version: "11.0.0"
57+
mdl: "EXECUTE DATABASE QUERY with runtime connection override"
58+
loop_in_branch:
59+
min_version: "10.0.0"
60+
notes: "LOOP inside IF/ELSE branches"
61+
62+
pages:
63+
basic:
64+
min_version: "10.0.0"
65+
mdl: "CREATE PAGE Module.Name (...) { ... }"
66+
page_parameters:
67+
min_version: "11.0.0"
68+
mdl: "CREATE PAGE Module.Name (Param: Type, ...) { ... }"
69+
page_variables:
70+
min_version: "11.0.0"
71+
pluggable_widgets:
72+
min_version: "10.0.0"
73+
notes: "Widget templates are version-specific; MPK augmentation handles drift"
74+
design_properties_v3:
75+
min_version: "11.0.0"
76+
notes: "Atlas v3 design properties (Card style, Disable row wrap)"
77+
alter_page:
78+
min_version: "10.0.0"
79+
mdl: "ALTER PAGE Module.Name SET/INSERT/DROP/REPLACE ..."
80+
81+
security:
82+
module_roles:
83+
min_version: "10.0.0"
84+
user_roles:
85+
min_version: "10.0.0"
86+
entity_access:
87+
min_version: "10.0.0"
88+
demo_users:
89+
min_version: "10.0.0"
90+
91+
integration:
92+
rest_client_basic:
93+
min_version: "10.1.0"
94+
mdl: "CREATE REST CLIENT Module.Name ..."
95+
rest_client_query_params:
96+
min_version: "11.0.0"
97+
mdl: "CREATE REST CLIENT with query parameters"
98+
rest_client_headers:
99+
min_version: "10.4.0"
100+
database_connector_basic:
101+
min_version: "10.6.0"
102+
mdl: "CREATE DATABASE CONNECTION Module.Name ..."
103+
database_connector_execute:
104+
min_version: "10.6.0"
105+
mdl: "EXECUTE DATABASE QUERY in microflows"
106+
business_events:
107+
min_version: "10.0.0"
108+
mdl: "CREATE BUSINESS EVENT SERVICE Module.Name ..."
109+
odata_client:
110+
min_version: "10.0.0"
111+
112+
workflows:
113+
basic:
114+
min_version: "9.0.0"
115+
mdl: "CREATE WORKFLOW Module.Name ..."
116+
parallel_split:
117+
min_version: "9.0.0"
118+
user_task:
119+
min_version: "9.0.0"
120+
121+
navigation:
122+
profiles:
123+
min_version: "10.0.0"
124+
menu_items:
125+
min_version: "10.0.0"
126+
home_pages:
127+
min_version: "10.0.0"
128+
129+
mpr_format:
130+
mpr_v2:
131+
min_version: "10.18.0"
132+
notes: "MPR metadata + mprcontents/ folder with individual documents"
133+
association_storage:
134+
min_version: "11.0.0"
135+
notes: "New association storage format"
136+
portable_app:
137+
min_version: "11.6.0"
138+
notes: "New portable app deployment format"

0 commit comments

Comments
 (0)