Skip to content

Commit 00041fa

Browse files
authored
Merge pull request #25601 from abpframework/salihozkara/low-code-public-schemas
Add low-code model descriptor schemas
2 parents dcf81f5 + 26cc997 commit 00041fa

39 files changed

Lines changed: 2517 additions & 0 deletions
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "command-interceptor-descriptor.schema.json",
4+
"title": "CommandInterceptorDescriptor",
5+
"description": "Describes a JavaScript interceptor for an entity Create, Update, or Delete command.",
6+
"markdownDescription": "AI guidance: use `type: \"Pre\"` to validate or block before persistence and `type: \"Post\"` for side effects after persistence. Scripts can inspect `context.commandArgs` and may use services exposed on `context` such as `db`, `currentUser`, `currentTenant`, `emailSender`, `config`, `http`, and logging helpers depending on host configuration. To block the command with a user-facing error, assign `globalError = \"message\"` and return. Keep scripts idempotent where possible.",
7+
"type": "object",
8+
"properties": {
9+
"commandName": {
10+
"type": "string",
11+
"description": "Entity command to intercept: Create, Update, or Delete.",
12+
"enum": ["Create", "Update", "Delete"]
13+
},
14+
"type": {
15+
"$ref": "interceptor-type.schema.json",
16+
"description": "Whether the script runs before or after the command."
17+
},
18+
"javascript": {
19+
"type": "string",
20+
"description": "JavaScript code to execute. For Pre interceptors, set globalError to block the command. Example: if (!context.commandArgs.data['Name']) { globalError = 'Name is required.'; }"
21+
}
22+
},
23+
"required": ["commandName", "type", "javascript"],
24+
"additionalProperties": false,
25+
"examples": [
26+
{
27+
"commandName": "Create",
28+
"type": "Pre",
29+
"javascript": "if (!context.commandArgs.data['Name']) { globalError = 'Name is required.'; }"
30+
},
31+
{
32+
"commandName": "Delete",
33+
"type": "Pre",
34+
"javascript": "var record = await db.get('Acme.Events.Event', context.commandArgs.entityId); if (record && record.Status === 2) { globalError = 'Completed events cannot be deleted.'; }"
35+
}
36+
]
37+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "dashboard-aggregation-type.schema.json",
4+
"title": "DashboardAggregationType",
5+
"description": "The type of aggregation to perform. Prefer lower-case values in descriptor JSON; PascalCase aliases are accepted for compatibility.",
6+
"markdownDescription": "`count` counts records and does not require a property. `sum`, `average`, `min`, and `max` require a property. `percentFilled` and `percentEmpty` calculate completeness for a nullable/string property.",
7+
"type": "string",
8+
"enum": [
9+
"count",
10+
"Count",
11+
"sum",
12+
"Sum",
13+
"average",
14+
"Average",
15+
"min",
16+
"Min",
17+
"max",
18+
"Max",
19+
"percentFilled",
20+
"PercentFilled",
21+
"percentEmpty",
22+
"PercentEmpty"
23+
],
24+
"enumDescriptions": [
25+
"Count matching records.",
26+
"Count matching records.",
27+
"Sum a numeric property.",
28+
"Sum a numeric property.",
29+
"Average a numeric property.",
30+
"Average a numeric property.",
31+
"Minimum property value.",
32+
"Minimum property value.",
33+
"Maximum property value.",
34+
"Maximum property value.",
35+
"Percentage of records where property has a value.",
36+
"Percentage of records where property has a value.",
37+
"Percentage of records where property is empty/null.",
38+
"Percentage of records where property is empty/null."
39+
]
40+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "dashboard-chart-descriptor.schema.json",
4+
"title": "DashboardChartDescriptor",
5+
"description": "Configuration for a chart visualization.",
6+
"markdownDescription": "AI guidance: use chart visualizations for grouped aggregations. `xAxis.property` is the grouping property. `yAxis` contains one or more aggregations. Use `count` without a property; use `sum`, `average`, `min`, or `max` with a numeric/date property. Use `dateGrouping` when xAxis is date/datetime.",
7+
"type": "object",
8+
"properties": {
9+
"chartType": {
10+
"$ref": "dashboard-chart-type.schema.json",
11+
"description": "Chart renderer type: bar, line, pie, or donut."
12+
},
13+
"xAxis": {
14+
"type": "object",
15+
"properties": {
16+
"property": {
17+
"type": "string",
18+
"description": "Property name to group by on the X-axis. Must exist on the visualization entity."
19+
},
20+
"useForeignDisplay": {
21+
"type": "boolean",
22+
"description": "Show the FK display property instead of the raw id when xAxis.property is a foreign key.",
23+
"default": false
24+
},
25+
"dateGrouping": {
26+
"type": ["string", "null"],
27+
"enum": ["", "day", "week", "month", "quarter", "year", null],
28+
"description": "Grouping interval for date/datetime properties. Omit or use empty string for no date grouping."
29+
}
30+
},
31+
"required": ["property"],
32+
"additionalProperties": false
33+
},
34+
"yAxis": {
35+
"type": "array",
36+
"items": {
37+
"type": "object",
38+
"properties": {
39+
"aggregation": {
40+
"$ref": "dashboard-aggregation-type.schema.json"
41+
},
42+
"property": {
43+
"type": ["string", "null"],
44+
"description": "Property name for sum/average/min/max/percent aggregations. Omit for count."
45+
},
46+
"label": {
47+
"type": ["string", "null"],
48+
"description": "Display label for this series. Omit to derive from aggregation/property."
49+
},
50+
"color": {
51+
"type": ["string", "null"]
52+
}
53+
},
54+
"required": ["aggregation"],
55+
"additionalProperties": false
56+
},
57+
"minItems": 1
58+
},
59+
"barOrientation": {
60+
"type": "string",
61+
"enum": ["vertical", "horizontal"],
62+
"default": "vertical"
63+
},
64+
"showRecordCount": {
65+
"type": "boolean",
66+
"default": false
67+
},
68+
"maxItems": {
69+
"type": "integer",
70+
"description": "Maximum number of grouped items to display in the chart.",
71+
"default": 10,
72+
"minimum": 1,
73+
"maximum": 50
74+
}
75+
},
76+
"required": ["chartType", "xAxis", "yAxis"],
77+
"additionalProperties": false,
78+
"examples": [
79+
{
80+
"chartType": "bar",
81+
"xAxis": { "property": "Status" },
82+
"yAxis": [{ "aggregation": "count", "label": "Events" }],
83+
"maxItems": 10
84+
},
85+
{
86+
"chartType": "line",
87+
"xAxis": { "property": "StartDate", "dateGrouping": "month" },
88+
"yAxis": [{ "aggregation": "sum", "property": "Budget", "label": "Budget" }]
89+
}
90+
]
91+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "dashboard-chart-type.schema.json",
4+
"title": "DashboardChartType",
5+
"description": "The type of chart. Prefer lower-case values in descriptor JSON; PascalCase aliases are accepted for compatibility.",
6+
"markdownDescription": "Use `bar` for categorical comparisons, `line` for trends over time, `pie`/`donut` for part-of-whole views with a small number of categories.",
7+
"type": "string",
8+
"enum": ["bar", "Bar", "line", "Line", "pie", "Pie", "donut", "Donut"],
9+
"enumDescriptions": [
10+
"Bar chart.",
11+
"Bar chart.",
12+
"Line chart.",
13+
"Line chart.",
14+
"Pie chart.",
15+
"Pie chart.",
16+
"Donut chart.",
17+
"Donut chart."
18+
]
19+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "dashboard-descriptor.schema.json",
4+
"title": "DashboardDescriptor",
5+
"description": "Describes a dashboard page configuration with global filters and rows of visualizations.",
6+
"markdownDescription": "AI guidance: a dashboard belongs to a page with `type: \"dashboard\"`. It contains one or more rows; each row contains chart, list, or numberContainer visualizations. Use visualization `entityName` to select data for chart/list items. Use numberContainer for KPI tiles, charts for grouped aggregations, and lists for recent/top records.",
7+
"type": "object",
8+
"properties": {
9+
"description": {
10+
"type": ["string", "null"],
11+
"description": "Optional description text shown below the dashboard title."
12+
},
13+
"globalFilters": {
14+
"type": "array",
15+
"description": "Global filters that affect visualizations, for example a date range. Visualizations can map the global date filter through globalDateFilterProperty.",
16+
"items": {
17+
"$ref": "dashboard-global-filter-descriptor.schema.json"
18+
}
19+
},
20+
"rows": {
21+
"type": "array",
22+
"description": "Dashboard rows. Each row contains one or more visualization items; width 2 items usually take the full row.",
23+
"items": {
24+
"$ref": "dashboard-row-descriptor.schema.json"
25+
},
26+
"minItems": 1
27+
}
28+
},
29+
"required": ["rows"],
30+
"additionalProperties": false,
31+
"examples": [
32+
{
33+
"description": "Operational overview",
34+
"rows": [
35+
{
36+
"items": [
37+
{
38+
"name": "events-by-status",
39+
"type": "chart",
40+
"title": "Events by Status",
41+
"entityName": "Acme.Events.Event",
42+
"chart": {
43+
"chartType": "bar",
44+
"xAxis": { "property": "Status" },
45+
"yAxis": [{ "aggregation": "count", "label": "Events" }]
46+
}
47+
}
48+
]
49+
}
50+
]
51+
}
52+
]
53+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "dashboard-filter-descriptor.schema.json",
4+
"title": "DashboardFilterDescriptor",
5+
"description": "Static filter applied to a dashboard visualization or KPI item.",
6+
"markdownDescription": "AI guidance: use dashboard filters to constrain the data behind a visualization, for example only active records or only records above a threshold. Each condition property must exist on the visualization/item entity. Combine conditions with `operator: \"and\"` or `operator: \"or\"`.",
7+
"type": "object",
8+
"properties": {
9+
"operator": {
10+
"type": "string",
11+
"enum": ["and", "or"],
12+
"default": "and"
13+
},
14+
"conditions": {
15+
"type": "array",
16+
"items": {
17+
"type": "object",
18+
"properties": {
19+
"property": {
20+
"type": "string",
21+
"description": "Property name to filter on. Must exist on the visualization/item entityName."
22+
},
23+
"filterType": {
24+
"type": "string",
25+
"enum": ["equal", "notEqual", "contains", "greaterThan", "lessThan", "isNull", "isNotNull"],
26+
"default": "equal"
27+
},
28+
"value": {
29+
"description": "Filter value. Shape depends on filterType and target property type."
30+
}
31+
},
32+
"required": ["property", "filterType"],
33+
"additionalProperties": false
34+
}
35+
}
36+
},
37+
"required": ["conditions"],
38+
"additionalProperties": false,
39+
"examples": [
40+
{
41+
"operator": "and",
42+
"conditions": [
43+
{ "property": "Status", "filterType": "equal", "value": 1 }
44+
]
45+
}
46+
]
47+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "dashboard-global-filter-descriptor.schema.json",
4+
"title": "DashboardGlobalFilterDescriptor",
5+
"description": "Describes a dashboard-level filter control that can affect all visualizations on the dashboard.",
6+
"markdownDescription": "AI guidance: use global filters for dashboard-wide controls, not for per-visualization conditions. The current supported type is `dateRange`; visualization filters can then reference date-like entity properties through their own `filter` or `userFilters` settings.",
7+
"type": "object",
8+
"properties": {
9+
"type": {
10+
"type": "string",
11+
"enum": ["dateRange"],
12+
"default": "dateRange",
13+
"description": "Global filter control type. Currently only 'dateRange' is supported."
14+
}
15+
},
16+
"required": ["type"],
17+
"additionalProperties": false,
18+
"examples": [
19+
{ "type": "dateRange" }
20+
]
21+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "dashboard-list-descriptor.schema.json",
4+
"title": "DashboardListDescriptor",
5+
"description": "Configuration for a dashboard list/table visualization.",
6+
"markdownDescription": "AI guidance: use list visualizations for recent records, top records, or compact operational queues. `fields` must contain property names from the parent visualization entityName. Use `sortBy` to make results deterministic.",
7+
"type": "object",
8+
"properties": {
9+
"fields": {
10+
"type": "array",
11+
"items": { "type": "string" },
12+
"description": "Property names to display as columns. Each value must reference a property on the visualization entityName."
13+
},
14+
"sortBy": {
15+
"type": "object",
16+
"properties": {
17+
"property": {
18+
"type": "string",
19+
"description": "Property name to sort by. Must exist on the visualization entityName."
20+
},
21+
"direction": {
22+
"type": "string",
23+
"enum": ["asc", "desc"],
24+
"default": "asc"
25+
}
26+
},
27+
"required": ["property"],
28+
"additionalProperties": false
29+
},
30+
"maxRows": {
31+
"type": "integer",
32+
"minimum": 1,
33+
"maximum": 50,
34+
"default": 10
35+
},
36+
"rowHeight": {
37+
"type": "string",
38+
"enum": ["compact", "normal", "tall"],
39+
"default": "compact"
40+
},
41+
"colorBy": {
42+
"oneOf": [
43+
{
44+
"type": "object",
45+
"properties": {
46+
"type": {
47+
"type": "string",
48+
"enum": ["property", "conditions"]
49+
},
50+
"property": {
51+
"type": "string",
52+
"description": "Enum/status property name for automatic coloring."
53+
}
54+
},
55+
"required": ["type"],
56+
"additionalProperties": false
57+
},
58+
{
59+
"type": "null"
60+
}
61+
]
62+
}
63+
},
64+
"required": ["fields"],
65+
"additionalProperties": false,
66+
"examples": [
67+
{
68+
"fields": ["Title", "StartDate", "Status"],
69+
"sortBy": { "property": "StartDate", "direction": "desc" },
70+
"maxRows": 10,
71+
"rowHeight": "compact",
72+
"colorBy": { "type": "property", "property": "Status" }
73+
}
74+
]
75+
}

0 commit comments

Comments
 (0)