@enfyra/mcp-server 0.0.35 → 0.0.37
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
package/src/lib/mcp-examples.js
CHANGED
|
@@ -590,6 +590,7 @@ create_menu({
|
|
|
590
590
|
'Keep /dashboard as a summary and distribution page, not a detailed operations table.',
|
|
591
591
|
'Use focused pages for operational domains.',
|
|
592
592
|
'Provisioning pages should not show raw history rows as the primary UI; group by project/run and translate step keys into operator-facing labels.',
|
|
593
|
+
'Operational lists should use pagination plus search/filter controls; do not rely on arbitrary fixed limits such as limit=50.',
|
|
593
594
|
'UTabs is available in eApp extension runtime for page-level sections.',
|
|
594
595
|
'Admin links for editing or inspecting records should point to /data/<table> routes.',
|
|
595
596
|
],
|
|
@@ -633,6 +634,56 @@ console.log(ok, requiredTerms.has('cloud-terms'), loaded, label, date)
|
|
|
633
634
|
'If diagnostics complain about these APIs, fix eApp extension TypeScript lib/runtime contract.',
|
|
634
635
|
],
|
|
635
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_cents: { sum: { _gte: 0 } }
|
|
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; do not sum varchar money fields.',
|
|
685
|
+
],
|
|
686
|
+
},
|
|
636
687
|
],
|
|
637
688
|
},
|
|
638
689
|
};
|
|
@@ -273,6 +273,10 @@ export function buildMcpServerInstructions(apiBaseUrl) {
|
|
|
273
273
|
'- **NO import statements.** All APIs are injected globally (see full list below).',
|
|
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
|
+
'- **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. Add/use a numeric amount field such as `amount_cents` or `amount` for revenue stats, or build a dedicated stats route that normalizes legacy values explicitly.',
|
|
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.',
|
|
276
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.',
|
|
277
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.',
|
|
278
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.',
|