@dforge-core/dforge-mcp 0.1.0-rc.9 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +84 -27
  3. package/dist/server.js +2957 -616
  4. package/docs/creating-modules.md +11 -4
  5. package/package.json +11 -6
  6. package/resources/docs/conventions.md +22 -16
  7. package/resources/docs/dsl-reference.md +767 -0
  8. package/resources/schemas/entity.schema.json +8 -1
  9. package/resources/schemas/print-templates.schema.json +82 -0
  10. package/resources/schemas/reports.schema.json +4 -0
  11. package/resources/schemas/triggers.schema.json +59 -0
  12. package/skills/dforge-mcp-author/SKILL.md +269 -69
  13. package/skills/dforge-mcp-author/examples/matrix-budget/README.md +43 -0
  14. package/skills/dforge-mcp-author/examples/matrix-budget/entities/budget_category.json +24 -0
  15. package/skills/dforge-mcp-author/examples/matrix-budget/entities/budget_line.json +56 -0
  16. package/skills/dforge-mcp-author/examples/matrix-budget/manifest.json +30 -0
  17. package/skills/dforge-mcp-author/examples/matrix-budget/security/roles.json +9 -0
  18. package/skills/dforge-mcp-author/examples/matrix-budget/seed-data/01-categories.json +8 -0
  19. package/skills/dforge-mcp-author/examples/matrix-budget/ui/data_views.json +42 -0
  20. package/skills/dforge-mcp-author/examples/simple-todo/README.md +38 -0
  21. package/skills/dforge-mcp-author/examples/simple-todo/entities/todo_item.json +83 -0
  22. package/skills/dforge-mcp-author/examples/simple-todo/entities/todo_list.json +43 -0
  23. package/skills/dforge-mcp-author/examples/simple-todo/logic/actions/mark_done.dsl +6 -0
  24. package/skills/dforge-mcp-author/examples/simple-todo/manifest.json +32 -0
  25. package/skills/dforge-mcp-author/examples/simple-todo/security/roles.json +10 -0
  26. package/skills/dforge-mcp-author/examples/simple-todo/seed-data/01-lists.json +17 -0
  27. package/skills/dforge-mcp-author/examples/simple-todo/ui/actions.json +11 -0
  28. package/skills/dforge-mcp-author/examples/simple-todo/ui/data_views.json +35 -0
  29. package/skills/dforge-mcp-author/examples/simple-todo/ui/menus.json +28 -0
  30. package/skills/dforge-mcp-author/references/action-dsl.md +397 -0
  31. package/skills/dforge-mcp-author/references/column-types.md +168 -0
  32. package/skills/dforge-mcp-author/references/conventions.md +177 -0
  33. package/skills/dforge-mcp-author/references/data-migration.md +270 -0
  34. package/skills/dforge-mcp-author/references/data-views.md +243 -0
  35. package/skills/dforge-mcp-author/references/excel-import.md +61 -0
  36. package/skills/dforge-mcp-author/references/field-types.md +144 -0
  37. package/skills/dforge-mcp-author/references/filters.md +326 -0
  38. package/skills/dforge-mcp-author/references/flags.md +73 -0
  39. package/skills/dforge-mcp-author/references/formulas.md +206 -0
  40. package/skills/dforge-mcp-author/references/jobs.md +149 -0
  41. package/skills/dforge-mcp-author/references/manifest.md +123 -0
  42. package/skills/dforge-mcp-author/references/menus.md +164 -0
  43. package/skills/dforge-mcp-author/references/number-sequences.md +117 -0
  44. package/skills/dforge-mcp-author/references/print-templates.md +159 -0
  45. package/skills/dforge-mcp-author/references/queries.md +312 -0
  46. package/skills/dforge-mcp-author/references/reports.md +398 -0
  47. package/skills/dforge-mcp-author/references/schema-import.md +331 -0
  48. package/skills/dforge-mcp-author/references/security.md +244 -0
  49. package/skills/dforge-mcp-author/references/settings.md +120 -0
  50. package/skills/dforge-mcp-author/references/traits.md +153 -0
  51. package/skills/dforge-mcp-author/references/translations.md +158 -0
  52. package/skills/dforge-mcp-author/references/validation-checklist.md +183 -0
  53. package/skills/dforge-mcp-author/scripts/xlsx_to_model.py +198 -0
@@ -0,0 +1,398 @@
1
+ # Reports Reference
2
+
3
+ Reports are **query-driven visualizations** — charts, KPIs, pivot tables, grids — backed by datasets. Unlike data views (which target one entity), reports can combine multiple datasets and render any layout.
4
+
5
+ Lives in: `ui/reports.json` or `ui/reports/<report_code>.json`
6
+ SP files: `logic/reports/rpt_*.sql`
7
+
8
+ ## Structure
9
+
10
+ ```json
11
+ {
12
+ "sales_pipeline": {
13
+ "description": "Open opportunities by stage",
14
+ "datasets": {
15
+ "ds_pipeline": {
16
+ "caption": "Pipeline Data",
17
+ "entityCode": "opportunity",
18
+ "columns": ["stage", "total_amount", "account"],
19
+ "filter": {
20
+ "g": "and",
21
+ "i": [
22
+ { "c": "stage", "o": "!in", "v": ["Closed Won", "Closed Lost"] }
23
+ ]
24
+ },
25
+ "groupBy": ["stage"],
26
+ "aggregations": {
27
+ "opp_count": { "func": "count", "column": "*" },
28
+ "total_value": { "func": "sum", "column": "total_amount" }
29
+ }
30
+ }
31
+ },
32
+ "layout": [
33
+ {
34
+ "vizType": "bar",
35
+ "datasetCd": "ds_pipeline",
36
+ "title": "Pipeline Value by Stage",
37
+ "config": {
38
+ "categoryCol": "stage",
39
+ "valueCol": "total_value",
40
+ "agg": "sum"
41
+ }
42
+ },
43
+ {
44
+ "vizType": "grid",
45
+ "datasetCd": "ds_pipeline",
46
+ "title": "Pipeline Detail"
47
+ }
48
+ ],
49
+ "params": {
50
+ "owner_filter": {
51
+ "fieldTypeCd": "user",
52
+ "label": "Filter by Owner",
53
+ "required": false
54
+ },
55
+ "start_date": {
56
+ "fieldTypeCd": "date",
57
+ "label": "Start Date",
58
+ "required": false,
59
+ "default": "=STARTMONTH()"
60
+ }
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ ## Dataset types
67
+
68
+ ### Entity query dataset (most common)
69
+
70
+ Queries an entity's data using the platform's query builder. Filters use the standard JSON filter format (see `references/filters.md`).
71
+
72
+ ```json
73
+ "ds_sales": {
74
+ "caption": "Sales Data",
75
+ "entityCode": "opportunity",
76
+ "columns": ["stage", "total_amount", "close_date", "account"],
77
+ "filter": { "c": "stage", "o": "!=", "v": "Closed Lost" },
78
+ "sort": [{ "column_cd": "close_date", "direction": "desc" }],
79
+ "groupBy": ["stage"],
80
+ "aggregations": {
81
+ "deal_count": { "func": "count", "column": "*" },
82
+ "total_value": { "func": "sum", "column": "total_amount" },
83
+ "avg_value": { "func": "avg", "column": "total_amount" }
84
+ }
85
+ }
86
+ ```
87
+
88
+ Aggregation functions: `count`, `sum`, `avg`, `min`, `max`.
89
+
90
+ ### Stored procedure dataset (developer path)
91
+
92
+ For complex SQL that the entity query can't express — window functions, CTEs, cross-schema joins, conditional aggregation, multi-result sets.
93
+
94
+ ```json
95
+ "aging_data": {
96
+ "caption": "AR Aging",
97
+ "datasetType": "S",
98
+ "sp": "rpt_ar_aging",
99
+ "params": {
100
+ "as_of_date": {
101
+ "fieldTypeCd": "date",
102
+ "label": "As of Date",
103
+ "required": true,
104
+ "default": "=NOW()"
105
+ },
106
+ "customer_id": {
107
+ "fieldTypeCd": "lookup",
108
+ "label": "Customer",
109
+ "required": false,
110
+ "params": { "entityCd": "customer" }
111
+ }
112
+ },
113
+ "columnsDef": {
114
+ "customer_name": {
115
+ "label": "Customer",
116
+ "fieldTypeCd": "text",
117
+ "baseDatatypeCd": "string",
118
+ "width": 200
119
+ },
120
+ "current_amount": {
121
+ "label": "Current",
122
+ "fieldTypeCd": "number",
123
+ "baseDatatypeCd": "number",
124
+ "format": "#,##0.00",
125
+ "width": 120
126
+ },
127
+ "days_30": {
128
+ "label": "1-30 Days",
129
+ "fieldTypeCd": "number",
130
+ "baseDatatypeCd": "number",
131
+ "format": "#,##0.00",
132
+ "width": 120
133
+ },
134
+ "total": {
135
+ "label": "Total",
136
+ "fieldTypeCd": "number",
137
+ "baseDatatypeCd": "number",
138
+ "format": "#,##0.00",
139
+ "width": 130
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ Key differences from entity datasets:
146
+ - `datasetType: "S"` (instead of default entity query)
147
+ - `sp` — the stored procedure function name (without schema — uses the module's schema)
148
+ - `columnsDef` — **required** — explicitly defines columns since the platform can't infer them from entity metadata
149
+ - Params can be defined per-dataset (dataset-level) or per-report (report-level)
150
+
151
+ ### The PostgreSQL function
152
+
153
+ SP files live in `logic/reports/` and follow this convention:
154
+
155
+ ```sql
156
+ CREATE OR REPLACE FUNCTION crm.rpt_ar_aging(
157
+ p_folder_uid uuid, -- REQUIRED: injected by platform (folder context)
158
+ p_user_id bigint, -- REQUIRED: injected by platform (current user)
159
+ p_as_of_date date DEFAULT NULL, -- User parameter
160
+ p_customer_id bigint DEFAULT NULL -- User parameter (optional)
161
+ )
162
+ RETURNS TABLE (
163
+ customer_name text,
164
+ current_amount numeric,
165
+ days_30 numeric,
166
+ days_60 numeric,
167
+ days_90 numeric,
168
+ over_90 numeric,
169
+ total numeric
170
+ )
171
+ LANGUAGE sql STABLE
172
+ AS $$
173
+ SELECT
174
+ c.account_name AS customer_name,
175
+ SUM(CASE WHEN age <= 30 THEN i.amount_due ELSE 0 END) AS current_amount,
176
+ SUM(CASE WHEN age BETWEEN 31 AND 60 THEN i.amount_due ELSE 0 END) AS days_30,
177
+ -- ... more columns ...
178
+ SUM(i.amount_due) AS total
179
+ FROM fin.invoice i
180
+ JOIN crm.account c ON c.account_id = i.customer_id
181
+ WHERE i.status != 'Paid'
182
+ AND (p_customer_id IS NULL OR i.customer_id = p_customer_id)
183
+ GROUP BY c.account_name
184
+ ORDER BY total DESC;
185
+ $$;
186
+ ```
187
+
188
+ **Rules for SP functions:**
189
+ - First two params are **always** `p_folder_uid uuid` and `p_user_id bigint` — injected by the platform
190
+ - User params come after, with `DEFAULT NULL` for optional ones
191
+ - Use `RETURNS TABLE (...)` for single result sets
192
+ - Use `RETURNS SETOF refcursor` for multiple result sets (advanced)
193
+ - Use the module's schema prefix: `crm.rpt_*`, `fin.rpt_*`, etc.
194
+ - Use `STABLE` volatility (read-only, enables PostgreSQL optimization)
195
+ - **Security is your responsibility** — filter by `p_folder_uid` and `p_user_id` where needed
196
+
197
+ ### Multi-result-set SPs
198
+
199
+ For reports with multiple related datasets from one query:
200
+
201
+ ```json
202
+ "datasets": {
203
+ "summary": {
204
+ "caption": "Department Summary",
205
+ "datasetType": "S",
206
+ "sp": "rpt_department_overview",
207
+ "spCursor": "department_summary",
208
+ "columnsDef": { /* ... */ }
209
+ },
210
+ "by_role": {
211
+ "caption": "By Role",
212
+ "datasetType": "S",
213
+ "sp": "rpt_department_overview",
214
+ "spCursor": "employee_breakdown",
215
+ "columnsDef": { /* ... */ }
216
+ }
217
+ }
218
+ ```
219
+
220
+ Multiple datasets share the same `sp` (function called once). `spCursor` maps each dataset to a named refcursor returned by the function.
221
+
222
+ ## Parameters
223
+
224
+ Parameters prompt the user for input before running the report (or action). Both reports and actions use the same parameter system.
225
+
226
+ ### Report-level parameters
227
+
228
+ Defined in the report's `params` object:
229
+
230
+ ```json
231
+ "params": {
232
+ "start_date": {
233
+ "fieldTypeCd": "date",
234
+ "label": "Start Date",
235
+ "required": true,
236
+ "default": "=STARTMONTH()"
237
+ },
238
+ "end_date": {
239
+ "fieldTypeCd": "date",
240
+ "label": "End Date",
241
+ "required": true,
242
+ "default": "=NOW()"
243
+ },
244
+ "region": {
245
+ "fieldTypeCd": "dropdown",
246
+ "label": "Region",
247
+ "required": false,
248
+ "params": {
249
+ "options": ["All", "North", "South", "East", "West"]
250
+ }
251
+ },
252
+ "customer": {
253
+ "fieldTypeCd": "lookup",
254
+ "label": "Customer",
255
+ "required": false,
256
+ "params": { "entityCd": "account" }
257
+ }
258
+ }
259
+ ```
260
+
261
+ ### Parameter properties
262
+
263
+ | Property | Description |
264
+ |---|---|
265
+ | `fieldTypeCd` | UI control type: `date`, `datetime`, `text`, `number`, `dropdown`, `lookup`, `user`, `checkbox` |
266
+ | `label` | Display label in the parameter dialog |
267
+ | `required` | Whether the user must fill this before running |
268
+ | `default` | Default value — plain value or formula with `=` prefix (e.g. `"=NOW()"`, `"=STARTMONTH()"`, `"=TODAY()"`) |
269
+ | `params` | Additional config — `options` for dropdowns, `entityCd` for lookups |
270
+
271
+ ### Using parameters in entity query filters
272
+
273
+ Reference parameters with `@param_code` in filter values:
274
+
275
+ ```json
276
+ "filter": {
277
+ "g": "and",
278
+ "i": [
279
+ { "c": "created_date", "o": ">=", "v": "@start_date" },
280
+ { "c": "created_date", "o": "<=", "v": "@end_date" }
281
+ ]
282
+ }
283
+ ```
284
+
285
+ ### Using parameters in SP datasets
286
+
287
+ Parameters are passed to the PostgreSQL function as positional arguments (after the two required system params). The order matches `params` declaration order in the dataset definition.
288
+
289
+ ### Action parameters (DSL)
290
+
291
+ Actions declare parameters in the `params:` block of the DSL file:
292
+
293
+ ```
294
+ params:
295
+ new_stage: dropdown required "New Stage"
296
+ note: textarea "Note"
297
+ amount: number required "Amount"
298
+ ```
299
+
300
+ Access in execute block: `params[param_name]`
301
+
302
+ See `references/action-dsl.md` for full syntax.
303
+
304
+ ### Named parameter sets (saved combos)
305
+
306
+ Users can save frequently-used parameter combinations for quick reuse. These are stored per-report or per-action and appear in a dropdown at the top of the parameter dialog. Defined at runtime (not in the module package).
307
+
308
+ ### Cross-parameter validation
309
+
310
+ Parameters can have cross-validation rules (e.g. `end_date >= start_date`). This is configured via a `validate` formula on the parameter set. For module packages, validation is typically handled by sensible defaults rather than explicit cross-validation formulas.
311
+
312
+ ## Layout
313
+
314
+ The `layout` array defines how datasets are visualized:
315
+
316
+ ```json
317
+ "layout": [
318
+ {
319
+ "vizType": "bar",
320
+ "datasetCd": "ds_pipeline",
321
+ "title": "Pipeline by Stage",
322
+ "config": {
323
+ "categoryCol": "stage",
324
+ "valueCol": "total_value",
325
+ "agg": "sum",
326
+ "chartSize": "l"
327
+ }
328
+ },
329
+ {
330
+ "vizType": "grid",
331
+ "datasetCd": "ds_pipeline",
332
+ "title": "Detail"
333
+ },
334
+ {
335
+ "vizType": "kpi",
336
+ "datasetCd": "ds_pipeline",
337
+ "title": "Total Value",
338
+ "config": {
339
+ "valueCol": "total_value",
340
+ "format": "currency"
341
+ }
342
+ },
343
+ {
344
+ "vizType": "pie",
345
+ "datasetCd": "ds_pipeline",
346
+ "title": "Distribution",
347
+ "config": {
348
+ "categoryCol": "stage",
349
+ "valueCol": "opp_count"
350
+ }
351
+ }
352
+ ]
353
+ ```
354
+
355
+ ### Visualization types
356
+
357
+ | `vizType` | Description | Config |
358
+ |---|---|---|
359
+ | `grid` | Tabular data with sort/filter | — |
360
+ | `bar` | Vertical bar chart | `categoryCol`, `valueCol`, `agg` |
361
+ | `bar-stacked` | Stacked vertical bar | `categoryCol`, `valueCol`, `stackCol`, `agg` |
362
+ | `h-bar` | Horizontal bar | Same as `bar` |
363
+ | `line` | Line chart | `categoryCol`, `valueCol`, `agg` |
364
+ | `area` | Area chart | Same as `line` |
365
+ | `pie` | Pie chart | `categoryCol`, `valueCol` |
366
+ | `doughnut` | Doughnut chart | Same as `pie` |
367
+ | `scatter` | Scatter plot | `xCol`, `yCol` |
368
+ | `combo` | Combined bar + line | `categoryCol`, `barCol`, `lineCol` |
369
+ | `kpi` | Single value card | `valueCol`, `format` (optional: gauge, progress, sparkline, icon variants) |
370
+ | `pivot` | Pivot table | `rowCols`, `colCols`, `valueCols`, `aggFunc` |
371
+
372
+ ### Chart size
373
+
374
+ Chart visualizations support an optional `config.chartSize` property to control the default display height.
375
+
376
+ | Field | Type | Allowed values | Description |
377
+ |---|---|---|---|
378
+ | `config.chartSize` | string | `sm`, `m`, `l`, `xl` | Optional size preset for chart height. When omitted, the default is `m`. |
379
+
380
+ ## Grants
381
+
382
+ Report access is granted via the `E` right:
383
+
384
+ ```json
385
+ "rights": {
386
+ "report.sales_pipeline": "E"
387
+ }
388
+ ```
389
+
390
+ ## Common mistakes
391
+
392
+ - Mixing `entityCode` + SP fields (`datasetType`, `sp`, `columnsDef`) in the same dataset — pick one source type.
393
+ - Forgetting `columnsDef` on SP datasets — **required** (platform can't infer columns from a function).
394
+ - Forgetting to grant `E` access in at least one role — report becomes invisible.
395
+ - Forgetting `p_folder_uid` and `p_user_id` as first two SP function params — call will fail.
396
+ - Using `panels` instead of `layout` for the visualization array — use `layout`.
397
+ - Using `widget` instead of `vizType` — use `vizType`.
398
+ - Referencing a parameter as `$param` — use `@param_code` in filters.