Admin widget builder
Widget live preview validation
F030 connects the applied builder payload to preview-safe backend validation endpoints only. Persisted save remains fail-closed until authenticated admin save, ownership guard and audit evidence are wired.
F030 · live preview validation · no persisted save
Admin widget live preview validation
این صفحه فقط endpointهای preview-safe بکاند را صدا میزند: validate-config، runtime-config-preview و embed-snippet-preview. مسیر create/update واقعی عمداً صدا زده نمیشود و هیچ admin token یا runtime token از UI گرفته نمیشود.
Timeout: 2200ms per endpoint
Runtime/admin token: never requested here
Persisted save: fail-closed
هنوز live preview اجرا نشده است. اگر بکاند روی `localhost:3000` روشن نباشد، نتیجه blocked شبکه/CORS طبیعی است؛ این صفحه برای smoke واقعی backend preview endpointهاست، نه ذخیره نهایی.
Preview payload
{
"tenantId": "tenant_frontend_preview",
"license": {
"id": "license_frontend_preview",
"tenantId": "tenant_frontend_preview",
"status": "active",
"expiresAtMs": null,
"revokedAtMs": null
},
"widgetType": {
"id": "widget_type_advanced_chart",
"code": "advanced_chart",
"version": 1,
"status": "active",
"configSchemaJson": {
"type": "object",
"additionalProperties": true
},
"defaultConfigJson": {
"symbol": "BINANCE:BTCUSDT",
"symbols": [
"BINANCE:BTCUSDT"
],
"interval": "1h",
"intervals": [
"1m",
"5m",
"15m",
"30m",
"1h",
"4h",
"1d"
],
"theme": "dark",
"locale": "fa",
"use_container_size": true,
"transparent_background": false,
"legal_branding": "backend_managed",
"features": {
"indicators": true,
"drawings": true,
"fullscreen": true,
"realtime": false,
"compare": false,
"alerts": false,
"events": false,
"trading": false,
"watchlist": false,
"heatmapZoom": false,
"screening": false,
"calendar": false,
"news": false,
"technicalAnalysis": false,
"fundamentals": false,
"timeline": false
}
},
"symbolRequirement": "single_required",
"websiteEmbed": {
"category": "website_embeddable_widgets",
"mode": "iframe"
}
},
"plan": {
"maxWidgets": 10,
"currentWidgetCount": 1,
"maxSymbols": 20,
"allowedWidgetTypes": [
"advanced_chart",
"advanced_chart@v1"
],
"allowedSymbols": [
"BINANCE:BTCUSDT"
],
"allowedIntervals": [
"1m",
"5m",
"15m",
"30m",
"1h",
"4h",
"1d"
],
"featureFlags": {
"indicators": true,
"drawings": true,
"fullscreen": true,
"realtime": false,
"compare": false,
"alerts": false,
"events": false,
"trading": false,
"watchlist": false,
"heatmapZoom": false,
"screening": false,
"calendar": false,
"news": false,
"technicalAnalysis": false,
"fundamentals": false,
"timeline": false
},
"legalBrandingFeatureFlags": {
"hideAttribution": false
}
},
"name": "Advanced KLine Chart",
"code": "demo-advanced-kline",
"configJson": {
"widget_type": "advanced-kline-chart",
"symbol": "BINANCE:BTCUSDT",
"symbols": [
"BINANCE:BTCUSDT"
],
"interval": "1h",
"intervals": [
"1m",
"5m",
"15m",
"30m",
"1h",
"4h",
"1d"
],
"theme": "dark",
"locale": "fa",
"direction": "auto",
"use_container_size": true,
"transparent_background": false,
"features": {
"indicators": true,
"drawings": true,
"fullscreen": true,
"realtime": false,
"compare": false,
"alerts": false,
"events": false,
"trading": false,
"watchlist": false,
"heatmapZoom": false,
"screening": false,
"calendar": false,
"news": false,
"technicalAnalysis": false,
"fundamentals": false,
"timeline": false
},
"klinecharts": {
"chart_style": "candlestick",
"frontend_widget_type": "advanced-kline-chart",
"mvp_stage": "v1",
"render_mode": "chart-runtime"
}
},
"allowedSymbolsJson": [
"BINANCE:BTCUSDT"
],
"allowedIntervalsJson": [
"1m",
"5m",
"15m",
"30m",
"1h",
"4h",
"1d"
],
"locale": "fa",
"runtimeFeaturesJson": {
"indicators": true,
"drawings": true,
"fullscreen": true,
"realtime": false,
"compare": false,
"alerts": false,
"events": false,
"trading": false,
"watchlist": false,
"heatmapZoom": false,
"screening": false,
"calendar": false,
"news": false,
"technicalAnalysis": false,
"fundamentals": false,
"timeline": false
},
"parentContainer": {
"width": 960,
"height": 610,
"minHeight": 520,
"display": "grid"
}
}Safety policy
- • Only preview-safe admin widget endpoints are called.
- • `POST /api/admin/widget-instances` and `PATCH /api/admin/widget-instances/:id` stay disabled.
- • Embed snippet uses placeholders only; no runtime token is copied or rendered.
- • Result normalizer redacts token-like evidence before display.