@enfyra/mcp-server 0.0.36 → 0.0.38

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enfyra/mcp-server",
3
- "version": "0.0.36",
3
+ "version": "0.0.38",
4
4
  "description": "MCP server for Enfyra - manage your Enfyra instance via Claude Code",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -634,6 +634,56 @@ console.log(ok, requiredTerms.has('cloud-terms'), loaded, label, date)
634
634
  'If diagnostics complain about these APIs, fix eApp extension TypeScript lib/runtime contract.',
635
635
  ],
636
636
  },
637
+ {
638
+ name: 'Dashboard aggregate stats with a time range',
639
+ code: `<script setup>
640
+ const range = ref('7d')
641
+ const now = () => new Date()
642
+ const rangeStart = computed(() => {
643
+ const d = now()
644
+ if (range.value === '24h') d.setHours(d.getHours() - 24)
645
+ else if (range.value === '30d') d.setDate(d.getDate() - 30)
646
+ else d.setDate(d.getDate() - 7)
647
+ return d.toISOString()
648
+ })
649
+
650
+ const flowStats = useApi('/flow_execution_definition', {
651
+ query: computed(() => ({
652
+ fields: 'id',
653
+ limit: 1,
654
+ meta: 'filterCount',
655
+ filter: { startedAt: { _gte: rangeStart.value } },
656
+ aggregate: {
657
+ id: { count: true },
658
+ status: { count: { _eq: 'failed' } }
659
+ }
660
+ }))
661
+ })
662
+
663
+ const orderStats = useApi('/cloud_payment_orders', {
664
+ query: computed(() => ({
665
+ fields: 'id',
666
+ limit: 1,
667
+ meta: 'filterCount',
668
+ filter: { createdAt: { _gte: rangeStart.value } },
669
+ aggregate: {
670
+ id: { count: true },
671
+ status: { count: { _eq: 'applied' } },
672
+ amount_usd: { sum: true }
673
+ }
674
+ }))
675
+ })
676
+
677
+ watch(range, () => Promise.all([flowStats.execute(), orderStats.execute()]))
678
+ onMounted(() => Promise.all([flowStats.execute(), orderStats.execute()]))
679
+ </script>`,
680
+ notes: [
681
+ 'Aggregate keys must be real fields or relations.',
682
+ 'Read results from response.meta.aggregate.',
683
+ 'Use top-level filter for time windows and cross-field conditions.',
684
+ 'sum/avg require numeric fields; amount_usd must be a real float/numeric SQL column, not metadata-only float over a varchar physical column.',
685
+ ],
686
+ },
637
687
  ],
638
688
  },
639
689
  };
@@ -274,6 +274,9 @@ export function buildMcpServerInstructions(apiBaseUrl) {
274
274
  '- **Design first for dashboards:** before creating/updating a dashboard extension, define the menu/page split, time range controls, tabs, and drill-down links. Keep `/dashboard` as a compact summary and routing hub only: KPIs, current signal, attention queue, and navigation cards. Put detailed lists/tables/timelines into focused pages such as projects, provisioning, billing, infrastructure, and readiness.',
275
275
  '- **Operational page modeling:** model admin operational pages around the operator mental entity, not raw database/event rows. For provisioning, group history by project/run, translate internal step keys into readable labels, show current step, operator meaning, and next action, and keep raw history as a secondary `/data` shortcut.',
276
276
  '- **Operational list data loading:** do not use arbitrary fixed limits such as `limit=50` as the whole data strategy for admin pages. Use pagination, expose result count when the API supports `meta=filterCount`, and add search/filter controls for natural lookup keys such as project id, name, and subdomain.',
277
+ '- **ESV aggregate contract:** aggregate query must be an object keyed by a real field or relation, for example `aggregate: { id: { count: true }, status: { count: { _eq: "failed" } }, amount: { sum: true } }`. Results are returned in `response.meta.aggregate`. Time windows and cross-field conditions belong in top-level `filter`, not inside a field aggregate condition. Field aggregate conditions only support operators on that same field; relation aggregates use `countRecords`.',
278
+ '- **Aggregate numeric rule:** `sum` and `avg` require a numeric field in ESV. Do not aggregate money stored as varchar/text. Use a numeric money field such as `amount_usd` with type `float`, `amount_cents`, or `amount` for revenue stats, or build a dedicated stats route that normalizes legacy values explicitly. If metadata says `float` but SQL aggregate still fails with `sum(character varying)`, the Enfyra Server physical schema is stale or missing the SQL float DDL mapping and must be redeployed/healed before relying on aggregate.',
279
+ '- **Dashboard stats:** time range buttons must change the query filter and reload stats. Cloud dashboard should summarize flow execution errors from `flow_execution_definition` and billing stats from order/subscription records; successful/no-error flow runs do not need a standalone provisioning menu.',
277
280
  '- **Page layout default:** page extensions should render full-bleed inside the app shell by default. The extension root is already inside the eApp page `<main>`, so do not add root-level page padding such as `p-4 sm:p-6 xl:p-8`; use spacing between internal sections only. Do not wrap the entire page in a centered card/container unless explicitly requested. Use responsive grids/stacks from the first version so the page works on desktop, tablet, and mobile.',
278
281
  '- **Admin record links:** when an admin extension links to backend records for management or inspection, point to eApp data routes such as `/data/landing_terms`, `/data/cloud_projects`, or `/data/cloud_payment_orders`. Do not use public landing-page paths from record fields such as `/cloud-terms` unless the explicit intent is previewing the public website.',
279
282
  '- **Do not downgrade extension code to ES5 to appease tooling.** eApp extension runtime should support normal browser/runtime APIs such as `Array.includes`, `Set`, `Promise.all`, `String.replace`, `Intl.DateTimeFormat`, and `Intl.NumberFormat`. If diagnostics reject these, fix eApp extension checker/runtime contract instead of rewriting generated extension code around the limitation.',