@littlebearapps/platform-admin-sdk 2.0.0 → 2.2.0
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/README.md +4 -7
- package/dist/templates.d.ts +1 -1
- package/dist/templates.js +206 -4
- package/package.json +1 -1
- package/templates/full/dashboard/src/components/notifications/NotificationDropdown.tsx +130 -0
- package/templates/full/dashboard/src/components/notifications/NotificationItem.tsx +264 -0
- package/templates/full/dashboard/src/components/patterns/PatternInfoButton.tsx +60 -0
- package/templates/full/dashboard/src/components/reports/DigestStats.tsx +151 -0
- package/templates/full/dashboard/src/components/reports/FeatureUsageReport.tsx +339 -0
- package/templates/full/dashboard/src/components/reports/HealthTrendsReport.tsx +192 -0
- package/templates/full/dashboard/src/components/search/SearchResultGroup.tsx +46 -0
- package/templates/full/dashboard/src/components/search/SearchResultItem.tsx +212 -0
- package/templates/full/dashboard/src/components/usage/AIModelBreakdown.tsx +364 -0
- package/templates/full/dashboard/src/components/usage/unified/Recommendations.tsx +149 -0
- package/templates/full/dashboard/src/lib/cloudflare/alerting.ts +486 -0
- package/templates/full/dashboard/src/lib/cloudflare/graphql.ts +4785 -0
- package/templates/full/dashboard/src/lib/cloudflare/project-registry.ts +451 -0
- package/templates/full/dashboard/src/lib/notifications/api.ts +197 -0
- package/templates/full/dashboard/src/lib/notifications/types.ts.hbs +97 -0
- package/templates/full/dashboard/src/lib/patterns/api.ts +120 -0
- package/templates/full/dashboard/src/lib/patterns/types.ts +127 -0
- package/templates/full/dashboard/src/lib/reports/types.ts +231 -0
- package/templates/full/dashboard/src/lib/search/api.ts +258 -0
- package/templates/full/dashboard/src/lib/search/types.ts.hbs +115 -0
- package/templates/full/dashboard/src/lib/settings/api.ts.hbs +201 -0
- package/templates/full/dashboard/src/lib/settings/types.ts.hbs +104 -0
- package/templates/full/dashboard/src/lib/usage/allowance-config.ts.hbs +547 -0
- package/templates/full/dashboard/src/lib/usage/providers.ts +331 -0
- package/templates/full/dashboard/src/pages/api/patterns/[id]/approve.ts +49 -0
- package/templates/full/dashboard/src/pages/api/patterns/[id]/reject.ts +50 -0
- package/templates/full/dashboard/src/pages/api/reports/digests/stats.ts +38 -0
- package/templates/full/dashboard/src/pages/api/reports/digests.ts +39 -0
- package/templates/full/dashboard/src/pages/api/search/reindex/[type].ts +56 -0
- package/templates/full/dashboard/src/pages/api/test-reports/[id].ts +102 -0
- package/templates/full/dashboard/src/pages/feedback.astro +365 -0
- package/templates/full/dashboard/src/pages/kiosk.astro +206 -0
- package/templates/full/dashboard/src/pages/map.astro +561 -0
- package/templates/full/dashboard/src/pages/revenue.astro +72 -0
- package/templates/full/dashboard/src/pages/tests.astro +431 -0
- package/templates/full/scripts/ops/audit-cost-anomaly.ts +430 -0
- package/templates/full/scripts/ops/verify-account-total.ts +256 -0
- package/templates/full/tests/integration/feedback-schema.test.ts +361 -0
- package/templates/full/tests/integration/r2-archive.test.ts +108 -0
- package/templates/shared/.github/workflows/dependabot-automerge.yml +41 -0
- package/templates/shared/.github/workflows/validate-controls.yml +27 -0
- package/templates/shared/dashboard/src/components/Breadcrumbs.astro +101 -0
- package/templates/shared/dashboard/src/components/EmptyState.astro +46 -0
- package/templates/shared/dashboard/src/components/ErrorBoundary.astro +79 -0
- package/templates/shared/dashboard/src/components/LoadingSkeleton.astro +105 -0
- package/templates/shared/dashboard/src/components/PageShell.astro +72 -0
- package/templates/shared/dashboard/src/components/SkipLinks.astro +22 -0
- package/templates/shared/dashboard/src/components/Toast.astro +170 -0
- package/templates/shared/dashboard/src/components/ToastContainer.astro +156 -0
- package/templates/shared/dashboard/src/components/costs/ProviderCostsGrid.tsx +401 -0
- package/templates/shared/dashboard/src/components/costs/index.ts +4 -0
- package/templates/shared/dashboard/src/components/overview/AlertBanner.tsx +94 -0
- package/templates/shared/dashboard/src/components/overview/index.ts +9 -0
- package/templates/shared/dashboard/src/components/reports/ReportInfoButton.tsx +98 -0
- package/templates/shared/dashboard/src/components/resources/CostChart.tsx +170 -0
- package/templates/shared/dashboard/src/components/resources/ProviderCard.tsx +272 -0
- package/templates/shared/dashboard/src/components/resources/ProviderDetail.tsx +293 -0
- package/templates/shared/dashboard/src/components/settings/SettingsCard.astro +102 -0
- package/templates/shared/dashboard/src/components/usage/AllowanceGauge.astro +170 -0
- package/templates/shared/dashboard/src/components/usage/AnomalyAlerts.astro +633 -0
- package/templates/shared/dashboard/src/components/usage/BillingCycleCountdown.astro +192 -0
- package/templates/shared/dashboard/src/components/usage/BurnRateHero.astro +539 -0
- package/templates/shared/dashboard/src/components/usage/CircuitBreakerEventLog.astro +542 -0
- package/templates/shared/dashboard/src/components/usage/CircuitBreakerPanel.tsx +292 -0
- package/templates/shared/dashboard/src/components/usage/CircuitBreakerStatus.astro +669 -0
- package/templates/shared/dashboard/src/components/usage/CompactThresholdBanner.astro +531 -0
- package/templates/shared/dashboard/src/components/usage/ComparisonModeSelector.astro +651 -0
- package/templates/shared/dashboard/src/components/usage/CostBreakdownChart.astro +381 -0
- package/templates/shared/dashboard/src/components/usage/CostBreakdownTable.astro +210 -0
- package/templates/shared/dashboard/src/components/usage/CostDataTable.astro +0 -0
- package/templates/shared/dashboard/src/components/usage/CostDonutChart.astro +311 -0
- package/templates/shared/dashboard/src/components/usage/DailyCostChart.astro +632 -0
- package/templates/shared/dashboard/src/components/usage/ExportButton.astro +114 -0
- package/templates/shared/dashboard/src/components/usage/FeatureBudgetsTable.astro +872 -0
- package/templates/shared/dashboard/src/components/usage/FilterBar.astro +190 -0
- package/templates/shared/dashboard/src/components/usage/FilterToggles.astro +175 -0
- package/templates/shared/dashboard/src/components/usage/GitHubUsageCard.astro +537 -0
- package/templates/shared/dashboard/src/components/usage/OverageCostCard.astro +212 -0
- package/templates/shared/dashboard/src/components/usage/PlanUtilizationCard.astro +193 -0
- package/templates/shared/dashboard/src/components/usage/ProjectCard.astro +640 -0
- package/templates/shared/dashboard/src/components/usage/ProjectCardsGrid.astro +272 -0
- package/templates/shared/dashboard/src/components/usage/ResourceSearch.astro +279 -0
- package/templates/shared/dashboard/src/components/usage/ServiceUtilizationList.astro +604 -0
- package/templates/shared/dashboard/src/components/usage/SparklineCard.astro +399 -0
- package/templates/shared/dashboard/src/components/usage/StatsHero.astro +600 -0
- package/templates/shared/dashboard/src/components/usage/TableFilters.astro +1033 -0
- package/templates/shared/dashboard/src/components/usage/ThresholdAlert.astro +271 -0
- package/templates/shared/dashboard/src/components/usage/ThresholdSettings.astro +618 -0
- package/templates/shared/dashboard/src/components/usage/TopSpenderCard.astro +170 -0
- package/templates/shared/dashboard/src/components/usage/UnifiedResourceTable.astro +1737 -0
- package/templates/shared/dashboard/src/components/usage/UsageCard.astro +135 -0
- package/templates/shared/dashboard/src/components/usage/UsageHealthBanner.astro +387 -0
- package/templates/shared/dashboard/src/components/usage/UtilizationBar.astro +159 -0
- package/templates/shared/dashboard/src/components/usage/WorkersBreakdownTable.astro +659 -0
- package/templates/shared/dashboard/src/components/usage/daily/CostChart.astro +461 -0
- package/templates/shared/dashboard/src/components/usage/daily/CostTable.astro +946 -0
- package/templates/shared/dashboard/src/components/usage/daily/DailyOverview.astro +1079 -0
- package/templates/shared/dashboard/src/components/usage/design-tokens.ts +187 -0
- package/templates/shared/dashboard/src/components/usage/filters/InlineDateRange.astro +285 -0
- package/templates/shared/dashboard/src/components/usage/filters/PeriodButtons.astro +157 -0
- package/templates/shared/dashboard/src/components/usage/filters/ProjectSelect.astro +284 -0
- package/templates/shared/dashboard/src/components/usage/react/DashboardShell.tsx +263 -0
- package/templates/shared/dashboard/src/components/usage/react/StatusBadge.tsx +77 -0
- package/templates/shared/dashboard/src/components/usage/react/UsageChart.tsx +391 -0
- package/templates/shared/dashboard/src/components/usage/react/index.ts.hbs +30 -0
- package/templates/shared/dashboard/src/components/usage/react/types.ts +137 -0
- package/templates/shared/dashboard/src/components/usage/scripts/ai-tab-controller.ts +419 -0
- package/templates/shared/dashboard/src/components/usage/scripts/constants.ts +60 -0
- package/templates/shared/dashboard/src/components/usage/scripts/formatters.ts +62 -0
- package/templates/shared/dashboard/src/components/usage/scripts/overview-controller.ts +1633 -0
- package/templates/shared/dashboard/src/components/usage/scripts/resource-table-builder.ts +294 -0
- package/templates/shared/dashboard/src/components/usage/scripts/tabs-filters-controller.ts +464 -0
- package/templates/shared/dashboard/src/components/usage/state/index.ts +55 -0
- package/templates/shared/dashboard/src/components/usage/state/usageActions.ts +439 -0
- package/templates/shared/dashboard/src/components/usage/state/usageStore.ts +376 -0
- package/templates/shared/dashboard/src/components/usage/transformers.ts +478 -0
- package/templates/shared/dashboard/src/components/usage/types.ts +283 -0
- package/templates/shared/dashboard/src/components/usage/unified/AlertBanner.tsx +172 -0
- package/templates/shared/dashboard/src/components/usage/unified/HeroCardsRow.tsx +757 -0
- package/templates/shared/dashboard/src/components/usage/unified/LiveHeader.tsx +169 -0
- package/templates/shared/dashboard/src/components/usage/unified/ProjectsTable.tsx +448 -0
- package/templates/shared/dashboard/src/components/usage/unified/ResourceBreakdown.tsx +236 -0
- package/templates/shared/dashboard/src/components/usage/unified/Sparkline.tsx +127 -0
- package/templates/shared/dashboard/src/components/usage/unified/UnifiedShell.tsx +893 -0
- package/templates/shared/dashboard/src/components/usage/unified/index.ts.hbs +50 -0
- package/templates/shared/dashboard/src/components/usage/unified/types.ts +416 -0
- package/templates/shared/dashboard/src/components/usage/usage-colors.ts +292 -0
- package/templates/shared/dashboard/src/lib/cloudflare/analytics.ts +310 -0
- package/templates/shared/dashboard/src/lib/cloudflare/d1.ts +55 -0
- package/templates/shared/dashboard/src/lib/cloudflare/index.ts.hbs +120 -0
- package/templates/shared/dashboard/src/lib/infrastructure/types.ts +116 -0
- package/templates/shared/dashboard/src/lib/usage/fetchWithDedup.ts +101 -0
- package/templates/shared/dashboard/src/lib/usage/index.ts.hbs +12 -0
- package/templates/shared/dashboard/src/pages/api/usage/ai-models.ts +235 -0
- package/templates/shared/dashboard/src/pages/api/usage/billing-context.ts +296 -0
- package/templates/shared/scripts/test-telemetry-flow.ts +464 -0
- package/templates/shared/tests/e2e/usage-api.test.ts +909 -0
- package/templates/shared/tests/e2e/usage-export.test.ts +784 -0
- package/templates/shared/tests/e2e/usage-mobile.test.ts +531 -0
- package/templates/shared/tests/helpers/mock-storage.ts +166 -0
- package/templates/shared/tests/integration/kv-cache.test.ts +252 -0
- package/templates/shared/tests/integration/platform-usage.test.ts +956 -0
- package/templates/shared/tests/unit/billing.test.ts +331 -0
- package/templates/shared/tests/unit/cloudflare/graphql.test.ts +217 -0
- package/templates/shared/tests/unit/components/usage-transformers.test.ts +473 -0
- package/templates/shared/tests/unit/control.test.ts +226 -0
- package/templates/shared/tests/unit/cost-calculator.test.ts +141 -0
- package/templates/shared/tests/unit/economics.test.ts +365 -0
- package/templates/shared/tests/unit/telemetry-sampling.test.ts +401 -0
- package/templates/standard/dashboard/src/components/errors/PriorityBadge.astro +27 -0
- package/templates/standard/dashboard/src/components/infrastructure/HealthchecksStatus.tsx +293 -0
- package/templates/standard/dashboard/src/components/infrastructure/InfrastructureTabs.tsx +268 -0
- package/templates/standard/dashboard/src/components/reports/CircuitBreakerReport.tsx +474 -0
- package/templates/standard/dashboard/src/components/reports/CostTrendsReport.tsx +229 -0
- package/templates/standard/dashboard/src/components/reports/ErrorTrendsReport.tsx +244 -0
- package/templates/standard/dashboard/src/components/reports/ProjectHealthTable.tsx +251 -0
- package/templates/standard/dashboard/src/components/reports/WarningDigestsTable.tsx +298 -0
- package/templates/standard/dashboard/src/components/usage/react/UsageTable.tsx +385 -0
- package/templates/standard/dashboard/src/components/usage/unified/CircuitBreakerEvents.tsx +305 -0
- package/templates/standard/dashboard/src/components/usage/unified/FeatureBudgets.tsx +472 -0
- package/templates/standard/dashboard/src/lib/errors/api.ts +84 -0
- package/templates/standard/dashboard/src/lib/errors/types.ts +75 -0
- package/templates/standard/dashboard/src/lib/infrastructure/api.ts +141 -0
- package/templates/standard/dashboard/src/lib/infrastructure/gatus.ts.hbs +112 -0
- package/templates/standard/dashboard/src/lib/services/proxy/index.ts +20 -0
- package/templates/standard/dashboard/src/lib/services/proxy/proxy.ts +244 -0
- package/templates/standard/dashboard/src/lib/services/proxy/types.ts +81 -0
- package/templates/standard/dashboard/src/pages/analytics.astro +64 -0
- package/templates/standard/dashboard/src/pages/api/infrastructure/alerts.ts +85 -0
- package/templates/standard/dashboard/src/pages/api/infrastructure/healthchecks/[id]/flips.ts +110 -0
- package/templates/standard/dashboard/src/pages/api/infrastructure/healthchecks.ts +101 -0
- package/templates/standard/dashboard/src/pages/api/infrastructure/uptime/[id]/response-times.ts +121 -0
- package/templates/standard/dashboard/src/pages/api/infrastructure/uptime.ts +89 -0
- package/templates/standard/dashboard/src/pages/api/test/service-auth.ts +178 -0
- package/templates/standard/tests/integration/connectors.test.ts +241 -0
- package/templates/standard/tests/integration/github-monitor.test.ts +143 -0
- package/templates/standard/tests/integration/ingestion.test.ts +211 -0
- package/templates/standard/tests/integration/platform-sentinel.test.ts +497 -0
- package/templates/standard/tests/unit/cloudflare/alerting.test.ts +480 -0
- package/templates/standard/tests/unit/error-collector/dedup.test.ts +350 -0
- package/templates/standard/tests/unit/error-collector/github.test.ts +187 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification Types
|
|
3
|
+
*
|
|
4
|
+
* TypeScript types for the platform notifications system.
|
|
5
|
+
*
|
|
6
|
+
* @module dashboard/lib/notifications/types
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Notification category (visual styling) */
|
|
10
|
+
export type NotificationCategory = 'error' | 'warning' | 'info' | 'success';
|
|
11
|
+
|
|
12
|
+
/** Notification priority (sorting/filtering) */
|
|
13
|
+
export type NotificationPriority = 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
14
|
+
|
|
15
|
+
/** Source systems that create notifications */
|
|
16
|
+
export type NotificationSource =
|
|
17
|
+
| 'error-collector'
|
|
18
|
+
| 'pattern-discovery'
|
|
19
|
+
| 'circuit-breaker'
|
|
20
|
+
| 'usage'
|
|
21
|
+
| 'gatus'
|
|
22
|
+
| 'system';
|
|
23
|
+
|
|
24
|
+
/** Project scope for notifications */
|
|
25
|
+
export type NotificationProject = 'platform' | '{{projectSlug}}' | null;
|
|
26
|
+
|
|
27
|
+
/** A single notification */
|
|
28
|
+
export interface Notification {
|
|
29
|
+
id: string;
|
|
30
|
+
category: NotificationCategory;
|
|
31
|
+
source: NotificationSource | string;
|
|
32
|
+
source_id: string | null;
|
|
33
|
+
title: string;
|
|
34
|
+
description: string | null;
|
|
35
|
+
priority: NotificationPriority;
|
|
36
|
+
action_url: string | null;
|
|
37
|
+
action_label: string | null;
|
|
38
|
+
project: NotificationProject;
|
|
39
|
+
created_at: number;
|
|
40
|
+
expires_at: number | null;
|
|
41
|
+
is_read?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Notification list response */
|
|
45
|
+
export interface NotificationListResponse {
|
|
46
|
+
notifications: Notification[];
|
|
47
|
+
count: number;
|
|
48
|
+
offset: number;
|
|
49
|
+
limit: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Unread count response */
|
|
53
|
+
export interface UnreadCountResponse {
|
|
54
|
+
count: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Mark as read response */
|
|
58
|
+
export interface MarkReadResponse {
|
|
59
|
+
success: boolean;
|
|
60
|
+
id?: string;
|
|
61
|
+
marked_count?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Digest frequency options */
|
|
65
|
+
export type DigestFrequency = 'realtime' | 'hourly' | 'daily' | 'weekly';
|
|
66
|
+
|
|
67
|
+
/** User notification preferences */
|
|
68
|
+
export interface NotificationPreferences {
|
|
69
|
+
email_enabled: boolean;
|
|
70
|
+
slack_enabled: boolean;
|
|
71
|
+
in_app_enabled: boolean;
|
|
72
|
+
digest_frequency: DigestFrequency;
|
|
73
|
+
muted_sources: string[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Request to create a notification */
|
|
77
|
+
export interface CreateNotificationRequest {
|
|
78
|
+
category: NotificationCategory;
|
|
79
|
+
source: NotificationSource | string;
|
|
80
|
+
source_id?: string;
|
|
81
|
+
title: string;
|
|
82
|
+
description?: string;
|
|
83
|
+
priority?: NotificationPriority;
|
|
84
|
+
action_url?: string;
|
|
85
|
+
action_label?: string;
|
|
86
|
+
project?: NotificationProject;
|
|
87
|
+
expires_at?: number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Query parameters for listing notifications */
|
|
91
|
+
export interface NotificationQueryParams {
|
|
92
|
+
project?: string;
|
|
93
|
+
source?: string;
|
|
94
|
+
category?: NotificationCategory;
|
|
95
|
+
limit?: number;
|
|
96
|
+
offset?: number;
|
|
97
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Discovery API Client
|
|
3
|
+
* Client functions for interacting with the pattern discovery API
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
PatternStats,
|
|
8
|
+
PatternsResponse,
|
|
9
|
+
SuggestionsResponse,
|
|
10
|
+
ActionResponse,
|
|
11
|
+
DiscoveryResult,
|
|
12
|
+
} from './types';
|
|
13
|
+
|
|
14
|
+
const BASE_URL = '/api/patterns';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Fetch approved patterns with match stats
|
|
18
|
+
*/
|
|
19
|
+
export async function fetchPatterns(
|
|
20
|
+
limit: number = 50,
|
|
21
|
+
offset: number = 0
|
|
22
|
+
): Promise<PatternsResponse> {
|
|
23
|
+
const response = await fetch(`${BASE_URL}?limit=${limit}&offset=${offset}`);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`Failed to fetch patterns: ${response.statusText}`);
|
|
26
|
+
}
|
|
27
|
+
return response.json();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Fetch pattern statistics summary
|
|
32
|
+
*/
|
|
33
|
+
export async function fetchPatternStats(): Promise<PatternStats> {
|
|
34
|
+
const response = await fetch(`${BASE_URL}/stats`);
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw new Error(`Failed to fetch pattern stats: ${response.statusText}`);
|
|
37
|
+
}
|
|
38
|
+
return response.json();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Fetch pending suggestions for review
|
|
43
|
+
* Note: This now also includes shadow patterns that have review_context
|
|
44
|
+
*/
|
|
45
|
+
export async function fetchSuggestions(limit: number = 20): Promise<SuggestionsResponse> {
|
|
46
|
+
const response = await fetch(`${BASE_URL}/suggestions?limit=${limit}`);
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw new Error(`Failed to fetch suggestions: ${response.statusText}`);
|
|
49
|
+
}
|
|
50
|
+
return response.json();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Fetch shadow patterns that are ready for review (have review_context)
|
|
55
|
+
*/
|
|
56
|
+
export async function fetchReadyForReview(limit: number = 20): Promise<SuggestionsResponse> {
|
|
57
|
+
const response = await fetch(`${BASE_URL}/ready-for-review?limit=${limit}`);
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
throw new Error(`Failed to fetch ready for review: ${response.statusText}`);
|
|
60
|
+
}
|
|
61
|
+
return response.json();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Approve a pending suggestion
|
|
66
|
+
*/
|
|
67
|
+
export async function approveSuggestion(
|
|
68
|
+
id: string,
|
|
69
|
+
by: string = 'dashboard'
|
|
70
|
+
): Promise<ActionResponse> {
|
|
71
|
+
const response = await fetch(`${BASE_URL}/${id}/approve?by=${encodeURIComponent(by)}`, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
});
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
const data = await response.json().catch(() => ({}));
|
|
76
|
+
throw new Error(data.error || `Failed to approve suggestion: ${response.statusText}`);
|
|
77
|
+
}
|
|
78
|
+
return response.json();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Reject a pending suggestion
|
|
83
|
+
*/
|
|
84
|
+
export async function rejectSuggestion(
|
|
85
|
+
id: string,
|
|
86
|
+
reason: string,
|
|
87
|
+
by: string = 'dashboard'
|
|
88
|
+
): Promise<ActionResponse> {
|
|
89
|
+
const response = await fetch(
|
|
90
|
+
`${BASE_URL}/${id}/reject?by=${encodeURIComponent(by)}&reason=${encodeURIComponent(reason)}`,
|
|
91
|
+
{ method: 'POST' }
|
|
92
|
+
);
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
const data = await response.json().catch(() => ({}));
|
|
95
|
+
throw new Error(data.error || `Failed to reject suggestion: ${response.statusText}`);
|
|
96
|
+
}
|
|
97
|
+
return response.json();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Refresh the KV cache of approved patterns
|
|
102
|
+
*/
|
|
103
|
+
export async function refreshPatternCache(): Promise<{ status: string }> {
|
|
104
|
+
const response = await fetch(`${BASE_URL}/cache-refresh`, { method: 'POST' });
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
throw new Error(`Failed to refresh cache: ${response.statusText}`);
|
|
107
|
+
}
|
|
108
|
+
return response.json();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Manually trigger pattern discovery
|
|
113
|
+
*/
|
|
114
|
+
export async function runDiscovery(): Promise<DiscoveryResult> {
|
|
115
|
+
const response = await fetch(`${BASE_URL}/discover`);
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
throw new Error(`Failed to run discovery: ${response.statusText}`);
|
|
118
|
+
}
|
|
119
|
+
return response.json();
|
|
120
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Discovery Types
|
|
3
|
+
* TypeScript types for the pattern discovery dashboard
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type PatternType = 'contains' | 'startsWith' | 'statusCode' | 'regex';
|
|
7
|
+
export type PatternScope = 'global' | 'script';
|
|
8
|
+
export type SuggestionStatus =
|
|
9
|
+
| 'pending'
|
|
10
|
+
| 'shadow'
|
|
11
|
+
| 'approved'
|
|
12
|
+
| 'stale'
|
|
13
|
+
| 'rejected'
|
|
14
|
+
| 'disabled';
|
|
15
|
+
export type PatternSource = 'ai-discovered' | 'static-import' | 'manual';
|
|
16
|
+
|
|
17
|
+
/** Review context for patterns ready for human approval */
|
|
18
|
+
export interface PatternReviewContext {
|
|
19
|
+
// Match evidence
|
|
20
|
+
totalMatches: number;
|
|
21
|
+
matchesByProject: Record<string, number>;
|
|
22
|
+
matchesByScript: Record<string, number>;
|
|
23
|
+
sampleMessages: string[];
|
|
24
|
+
distinctDays: number;
|
|
25
|
+
firstMatchAt: number | null;
|
|
26
|
+
lastMatchAt: number | null;
|
|
27
|
+
// Evaluation metadata
|
|
28
|
+
evaluatedAt: number;
|
|
29
|
+
recommendation: 'likely-approve' | 'needs-investigation' | 'likely-reject';
|
|
30
|
+
reasoning: string;
|
|
31
|
+
shadowMatchCount: number;
|
|
32
|
+
matchSpreadDays: number;
|
|
33
|
+
matchRate: number;
|
|
34
|
+
// AI-generated explainer (optional)
|
|
35
|
+
aiExplainer?: string | null;
|
|
36
|
+
whatItCatches?: string | null;
|
|
37
|
+
whyTransient?: string | null;
|
|
38
|
+
affectedAreas?: string | null;
|
|
39
|
+
concerns?: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface PatternSuggestion {
|
|
43
|
+
id: string;
|
|
44
|
+
patternType: PatternType;
|
|
45
|
+
patternValue: string;
|
|
46
|
+
category: string;
|
|
47
|
+
scope: PatternScope;
|
|
48
|
+
confidenceScore: number;
|
|
49
|
+
sampleMessages: string[];
|
|
50
|
+
aiReasoning: string;
|
|
51
|
+
clusterId: string | null;
|
|
52
|
+
status: SuggestionStatus;
|
|
53
|
+
reviewedBy: string | null;
|
|
54
|
+
reviewedAt: number | null;
|
|
55
|
+
rejectionReason: string | null;
|
|
56
|
+
backtestMatchCount: number | null;
|
|
57
|
+
backtestTotalErrors: number | null;
|
|
58
|
+
backtestMatchRate: number | null;
|
|
59
|
+
// Shadow mode tracking
|
|
60
|
+
shadowModeStart: number | null;
|
|
61
|
+
shadowModeEnd: number | null;
|
|
62
|
+
shadowModeMatches: number;
|
|
63
|
+
shadowMatchDays: string[];
|
|
64
|
+
// Lifecycle
|
|
65
|
+
enabledAt: number | null;
|
|
66
|
+
disabledAt: number | null;
|
|
67
|
+
lastMatchedAt: number | null;
|
|
68
|
+
matchCount: number;
|
|
69
|
+
// Self-tuning fields
|
|
70
|
+
isProtected: boolean;
|
|
71
|
+
source: PatternSource;
|
|
72
|
+
originalRegex: string | null;
|
|
73
|
+
// Review context for human approval (populated when ready for review)
|
|
74
|
+
reviewContext?: PatternReviewContext | null;
|
|
75
|
+
// Timestamps
|
|
76
|
+
createdAt: number;
|
|
77
|
+
updatedAt: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface PatternStats {
|
|
81
|
+
pendingCount: number;
|
|
82
|
+
shadowCount: number;
|
|
83
|
+
approvedCount: number;
|
|
84
|
+
staleCount: number;
|
|
85
|
+
rejectedCount: number;
|
|
86
|
+
disabledCount: number;
|
|
87
|
+
protectedCount: number;
|
|
88
|
+
staticCount: number;
|
|
89
|
+
totalMatches: number;
|
|
90
|
+
lastDiscoveryRun: number | null;
|
|
91
|
+
activeCategories: string[];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface DiscoveryResult {
|
|
95
|
+
runId: string;
|
|
96
|
+
runAt: number;
|
|
97
|
+
clustersFound: number;
|
|
98
|
+
clustersProcessed: number;
|
|
99
|
+
suggestionsCreated: number;
|
|
100
|
+
errors: string[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface ShadowEvaluationResult {
|
|
104
|
+
evaluated: number;
|
|
105
|
+
promoted: number;
|
|
106
|
+
demoted: number;
|
|
107
|
+
enteredShadow: number;
|
|
108
|
+
staleDetected: number;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface PatternsResponse {
|
|
112
|
+
patterns: PatternSuggestion[];
|
|
113
|
+
count: number;
|
|
114
|
+
limit: number;
|
|
115
|
+
offset: number;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface SuggestionsResponse {
|
|
119
|
+
suggestions: PatternSuggestion[];
|
|
120
|
+
count: number;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface ActionResponse {
|
|
124
|
+
success: boolean;
|
|
125
|
+
action: 'approved' | 'rejected' | 'entered-shadow';
|
|
126
|
+
error?: string;
|
|
127
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reports Types
|
|
3
|
+
* Types for the Reports section including warning digests
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Warning Digest Types
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
export interface WarningDigest {
|
|
11
|
+
id: string;
|
|
12
|
+
digest_date: string;
|
|
13
|
+
script_name: string;
|
|
14
|
+
fingerprint: string;
|
|
15
|
+
normalized_message: string;
|
|
16
|
+
github_repo: string;
|
|
17
|
+
github_issue_number: number | null;
|
|
18
|
+
github_issue_url: string | null;
|
|
19
|
+
occurrence_count: number;
|
|
20
|
+
first_occurrence_at: number;
|
|
21
|
+
last_occurrence_at: number;
|
|
22
|
+
created_at: number;
|
|
23
|
+
updated_at: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DigestFilter {
|
|
27
|
+
script?: string;
|
|
28
|
+
days?: number;
|
|
29
|
+
limit?: number;
|
|
30
|
+
offset?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface DigestListResponse {
|
|
34
|
+
digests: WarningDigest[];
|
|
35
|
+
total: number;
|
|
36
|
+
limit: number;
|
|
37
|
+
offset: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Digest Statistics Types
|
|
42
|
+
// ============================================================================
|
|
43
|
+
|
|
44
|
+
export interface DateStat {
|
|
45
|
+
digest_date: string;
|
|
46
|
+
count: number;
|
|
47
|
+
occurrences: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ScriptStat {
|
|
51
|
+
script_name: string;
|
|
52
|
+
count: number;
|
|
53
|
+
occurrences: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface RepoStat {
|
|
57
|
+
github_repo: string;
|
|
58
|
+
count: number;
|
|
59
|
+
occurrences: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface TopWarning {
|
|
63
|
+
normalized_message: string;
|
|
64
|
+
occurrences: number;
|
|
65
|
+
days_occurred: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface DigestStats {
|
|
69
|
+
byDate: DateStat[];
|
|
70
|
+
byScript: ScriptStat[];
|
|
71
|
+
byRepo: RepoStat[];
|
|
72
|
+
todayDigests: { count: number; occurrences: number };
|
|
73
|
+
yesterdayDigests: { count: number; occurrences: number };
|
|
74
|
+
totalDigests: number;
|
|
75
|
+
totalOccurrences: number;
|
|
76
|
+
topWarnings: TopWarning[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// Reports Hub Types
|
|
81
|
+
// ============================================================================
|
|
82
|
+
|
|
83
|
+
export type ReportType =
|
|
84
|
+
| 'warning-digests'
|
|
85
|
+
| 'sdk-audit'
|
|
86
|
+
| 'health-trends'
|
|
87
|
+
| 'circuit-breakers'
|
|
88
|
+
| 'gap-detection'
|
|
89
|
+
| 'feature-usage'
|
|
90
|
+
| 'error-trends'
|
|
91
|
+
| 'cost-trends';
|
|
92
|
+
|
|
93
|
+
export interface ReportCard {
|
|
94
|
+
id: ReportType;
|
|
95
|
+
name: string;
|
|
96
|
+
description: string;
|
|
97
|
+
href: string;
|
|
98
|
+
icon: string;
|
|
99
|
+
status: 'available' | 'coming_soon';
|
|
100
|
+
category: 'operations' | 'costs' | 'quality' | 'compliance';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ============================================================================
|
|
104
|
+
// SDK Audit Report Types
|
|
105
|
+
// ============================================================================
|
|
106
|
+
|
|
107
|
+
export interface AuditResult {
|
|
108
|
+
id: number;
|
|
109
|
+
project: string;
|
|
110
|
+
status: 'HEALTHY' | 'ZOMBIE' | 'UNTRACKED' | 'BROKEN';
|
|
111
|
+
ai_judge_score: number | null;
|
|
112
|
+
ai_judge_summary: string | null;
|
|
113
|
+
sdk_score: number;
|
|
114
|
+
observability_score: number;
|
|
115
|
+
cost_score: number;
|
|
116
|
+
security_score: number;
|
|
117
|
+
created_at: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface HealthTrend {
|
|
121
|
+
id: number;
|
|
122
|
+
project: string;
|
|
123
|
+
audit_date: string;
|
|
124
|
+
composite_score: number;
|
|
125
|
+
sdk_score: number;
|
|
126
|
+
observability_score: number;
|
|
127
|
+
cost_score: number;
|
|
128
|
+
security_score: number;
|
|
129
|
+
trend: 'improving' | 'stable' | 'declining';
|
|
130
|
+
score_delta: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// Circuit Breaker Report Types
|
|
135
|
+
// ============================================================================
|
|
136
|
+
|
|
137
|
+
export interface CircuitBreakerEvent {
|
|
138
|
+
id: number;
|
|
139
|
+
feature_id: string;
|
|
140
|
+
event_type: 'trip' | 'reset' | 'warning';
|
|
141
|
+
previous_state: string;
|
|
142
|
+
new_state: string;
|
|
143
|
+
reason: string;
|
|
144
|
+
threshold_value: number | null;
|
|
145
|
+
actual_value: number | null;
|
|
146
|
+
created_at: number;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface FeatureCircuitBreaker {
|
|
150
|
+
feature_id: string;
|
|
151
|
+
state: 'closed' | 'open' | 'half_open';
|
|
152
|
+
trip_count: number;
|
|
153
|
+
last_trip_at: number | null;
|
|
154
|
+
last_reset_at: number | null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// Gap Detection Report Types
|
|
159
|
+
// ============================================================================
|
|
160
|
+
|
|
161
|
+
export interface GapDetectionLog {
|
|
162
|
+
id: number;
|
|
163
|
+
detection_type: 'missing_hourly' | 'stale_project' | 'data_gap';
|
|
164
|
+
project: string | null;
|
|
165
|
+
resource_type: string | null;
|
|
166
|
+
gap_start: string;
|
|
167
|
+
gap_end: string | null;
|
|
168
|
+
gap_hours: number;
|
|
169
|
+
severity: 'low' | 'medium' | 'high';
|
|
170
|
+
resolved_at: number | null;
|
|
171
|
+
created_at: number;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ============================================================================
|
|
175
|
+
// Feature Usage Report Types
|
|
176
|
+
// ============================================================================
|
|
177
|
+
|
|
178
|
+
export interface FeatureUsageDaily {
|
|
179
|
+
id: number;
|
|
180
|
+
feature_id: string;
|
|
181
|
+
usage_date: string;
|
|
182
|
+
requests: number;
|
|
183
|
+
cpu_ms: number;
|
|
184
|
+
d1_reads: number;
|
|
185
|
+
d1_writes: number;
|
|
186
|
+
kv_reads: number;
|
|
187
|
+
kv_writes: number;
|
|
188
|
+
ai_neurons: number;
|
|
189
|
+
queue_messages: number;
|
|
190
|
+
estimated_cost_usd: number;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ============================================================================
|
|
194
|
+
// Error Trends Report Types
|
|
195
|
+
// ============================================================================
|
|
196
|
+
|
|
197
|
+
export interface ErrorTrendData {
|
|
198
|
+
date: string;
|
|
199
|
+
p0_count: number;
|
|
200
|
+
p1_count: number;
|
|
201
|
+
p2_count: number;
|
|
202
|
+
p3_count: number;
|
|
203
|
+
p4_count: number;
|
|
204
|
+
total_occurrences: number;
|
|
205
|
+
new_errors: number;
|
|
206
|
+
resolved_errors: number;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// Cost Trends Report Types
|
|
211
|
+
// ============================================================================
|
|
212
|
+
|
|
213
|
+
export interface DailyCost {
|
|
214
|
+
date: string;
|
|
215
|
+
workers_cost: number;
|
|
216
|
+
d1_cost: number;
|
|
217
|
+
kv_cost: number;
|
|
218
|
+
r2_cost: number;
|
|
219
|
+
ai_cost: number;
|
|
220
|
+
queue_cost: number;
|
|
221
|
+
total_cost: number;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface ProjectCost {
|
|
225
|
+
project: string;
|
|
226
|
+
total_cost: number;
|
|
227
|
+
workers_cost: number;
|
|
228
|
+
d1_cost: number;
|
|
229
|
+
kv_cost: number;
|
|
230
|
+
percentage_of_total: number;
|
|
231
|
+
}
|