@littlebearapps/platform-admin-sdk 1.5.0 → 2.1.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.
Files changed (157) hide show
  1. package/README.md +2 -2
  2. package/dist/templates.d.ts +1 -1
  3. package/dist/templates.js +197 -2
  4. package/package.json +1 -1
  5. package/templates/full/dashboard/src/components/patterns/ActivePatterns.tsx +62 -0
  6. package/templates/full/dashboard/src/components/patterns/PatternTabs.tsx +116 -0
  7. package/templates/full/dashboard/src/components/patterns/SystemPatterns.tsx +52 -0
  8. package/templates/full/dashboard/src/components/patterns/index.ts +3 -0
  9. package/templates/full/dashboard/src/components/reports/DigestStats.tsx +151 -0
  10. package/templates/full/dashboard/src/components/reports/GapDetectionReport.tsx +69 -0
  11. package/templates/full/dashboard/src/components/reports/HealthTrendsReport.tsx +192 -0
  12. package/templates/full/dashboard/src/components/reports/SdkAuditReport.tsx +72 -0
  13. package/templates/full/dashboard/src/components/reports/index.ts +2 -0
  14. package/templates/full/dashboard/src/components/usage/AIModelBreakdown.tsx +364 -0
  15. package/templates/full/dashboard/src/components/usage/unified/Recommendations.tsx +149 -0
  16. package/templates/full/dashboard/src/lib/cloudflare/alerting.ts +486 -0
  17. package/templates/full/dashboard/src/lib/cloudflare/graphql.ts +4785 -0
  18. package/templates/full/dashboard/src/lib/cloudflare/project-registry.ts +451 -0
  19. package/templates/full/dashboard/src/lib/notifications/api.ts +197 -0
  20. package/templates/full/dashboard/src/lib/notifications/types.ts.hbs +97 -0
  21. package/templates/full/dashboard/src/lib/patterns/api.ts +120 -0
  22. package/templates/full/dashboard/src/lib/patterns/types.ts +127 -0
  23. package/templates/full/dashboard/src/lib/reports/types.ts +231 -0
  24. package/templates/full/dashboard/src/lib/search/api.ts +258 -0
  25. package/templates/full/dashboard/src/lib/search/types.ts.hbs +115 -0
  26. package/templates/full/dashboard/src/lib/settings/api.ts.hbs +201 -0
  27. package/templates/full/dashboard/src/lib/settings/types.ts.hbs +104 -0
  28. package/templates/full/dashboard/src/lib/usage/allowance-config.ts.hbs +547 -0
  29. package/templates/full/dashboard/src/lib/usage/providers.ts +331 -0
  30. package/templates/full/dashboard/src/pages/api/notifications/[id]/read.ts +37 -0
  31. package/templates/full/dashboard/src/pages/api/notifications/read-all.ts +28 -0
  32. package/templates/full/dashboard/src/pages/api/patterns/cache-refresh.ts +38 -0
  33. package/templates/full/dashboard/src/pages/api/patterns/discover.ts +36 -0
  34. package/templates/full/dashboard/src/pages/api/patterns/ready-for-review.ts +39 -0
  35. package/templates/full/dashboard/src/pages/api/patterns/stats.ts +39 -0
  36. package/templates/full/dashboard/src/pages/api/patterns/suggestions.ts +43 -0
  37. package/templates/full/dashboard/src/pages/api/reports/audit.ts +45 -0
  38. package/templates/full/dashboard/src/pages/api/reports/usage.ts +52 -0
  39. package/templates/full/dashboard/src/pages/api/search/reindex.ts +28 -0
  40. package/templates/full/dashboard/src/pages/api/search/stats.ts +27 -0
  41. package/templates/full/dashboard/src/pages/api/settings/index.ts +37 -0
  42. package/templates/full/dashboard/src/pages/api/settings/update.ts +41 -0
  43. package/templates/full/dashboard/src/pages/api/topology/index.ts +56 -0
  44. package/templates/full/scripts/ops/universal-backfill.ts +147 -0
  45. package/templates/shared/.github/workflows/contract-check.yml.hbs +42 -0
  46. package/templates/shared/.github/workflows/dashboard-deploy.yml.hbs +39 -0
  47. package/templates/shared/.github/workflows/security.yml +33 -0
  48. package/templates/shared/dashboard/src/components/Nav.astro.hbs +2 -0
  49. package/templates/shared/dashboard/src/components/infrastructure/AlertHistory.tsx +57 -0
  50. package/templates/shared/dashboard/src/components/infrastructure/InfrastructureStats.tsx +73 -0
  51. package/templates/shared/dashboard/src/components/infrastructure/ServiceRegistry.tsx +55 -0
  52. package/templates/shared/dashboard/src/components/infrastructure/UptimeStatus.tsx +56 -0
  53. package/templates/shared/dashboard/src/components/infrastructure/index.ts +4 -0
  54. package/templates/shared/dashboard/src/components/reports/ReportInfoButton.tsx +98 -0
  55. package/templates/shared/dashboard/src/components/ui/Breadcrumbs.tsx +27 -0
  56. package/templates/shared/dashboard/src/components/ui/EmptyState.tsx +26 -0
  57. package/templates/shared/dashboard/src/components/ui/ErrorBoundary.tsx +42 -0
  58. package/templates/shared/dashboard/src/components/ui/LoadingSkeleton.tsx +18 -0
  59. package/templates/shared/dashboard/src/components/ui/PageShell.tsx +26 -0
  60. package/templates/shared/dashboard/src/components/ui/Toast.tsx +44 -0
  61. package/templates/shared/dashboard/src/components/ui/index.ts +6 -0
  62. package/templates/shared/dashboard/src/components/usage/AnomaliesWidget.tsx +68 -0
  63. package/templates/shared/dashboard/src/components/usage/HourlyUsageChart.tsx +55 -0
  64. package/templates/shared/dashboard/src/components/usage/PlanAllowanceDashboard.tsx +67 -0
  65. package/templates/shared/dashboard/src/components/usage/ProjectCostBreakdown.tsx +55 -0
  66. package/templates/shared/dashboard/src/components/usage/index.ts +4 -0
  67. package/templates/shared/dashboard/src/components/usage/react/DashboardShell.tsx +263 -0
  68. package/templates/shared/dashboard/src/components/usage/react/StatusBadge.tsx +77 -0
  69. package/templates/shared/dashboard/src/components/usage/react/UsageChart.tsx +391 -0
  70. package/templates/shared/dashboard/src/components/usage/react/index.ts.hbs +30 -0
  71. package/templates/shared/dashboard/src/components/usage/react/types.ts +137 -0
  72. package/templates/shared/dashboard/src/components/usage/transformers.ts +478 -0
  73. package/templates/shared/dashboard/src/components/usage/unified/AlertBanner.tsx +172 -0
  74. package/templates/shared/dashboard/src/components/usage/unified/HeroCardsRow.tsx +757 -0
  75. package/templates/shared/dashboard/src/components/usage/unified/LiveHeader.tsx +169 -0
  76. package/templates/shared/dashboard/src/components/usage/unified/ProjectsTable.tsx +448 -0
  77. package/templates/shared/dashboard/src/components/usage/unified/ResourceBreakdown.tsx +236 -0
  78. package/templates/shared/dashboard/src/components/usage/unified/Sparkline.tsx +127 -0
  79. package/templates/shared/dashboard/src/components/usage/unified/UnifiedShell.tsx +893 -0
  80. package/templates/shared/dashboard/src/components/usage/unified/index.ts.hbs +50 -0
  81. package/templates/shared/dashboard/src/components/usage/unified/types.ts +416 -0
  82. package/templates/shared/dashboard/src/lib/cloudflare/analytics.ts +310 -0
  83. package/templates/shared/dashboard/src/lib/cloudflare/costs.ts +21 -0
  84. package/templates/shared/dashboard/src/lib/cloudflare/d1.ts +55 -0
  85. package/templates/shared/dashboard/src/lib/cloudflare/index.ts.hbs +120 -0
  86. package/templates/shared/dashboard/src/lib/infrastructure/types.ts +116 -0
  87. package/templates/shared/dashboard/src/lib/usage/fetchWithDedup.ts +101 -0
  88. package/templates/shared/dashboard/src/lib/usage/index.ts.hbs +12 -0
  89. package/templates/shared/dashboard/src/pages/api/costs/overview.ts +65 -0
  90. package/templates/shared/dashboard/src/pages/api/costs/providers.ts +47 -0
  91. package/templates/shared/dashboard/src/pages/api/infrastructure/services.ts +55 -0
  92. package/templates/shared/dashboard/src/pages/api/infrastructure/stats.ts +99 -0
  93. package/templates/shared/dashboard/src/pages/api/usage/allowances.ts +56 -0
  94. package/templates/shared/dashboard/src/pages/api/usage/anomalies.ts +45 -0
  95. package/templates/shared/dashboard/src/pages/api/usage/billing.ts +53 -0
  96. package/templates/shared/dashboard/src/pages/api/usage/granular.ts +50 -0
  97. package/templates/shared/dashboard/src/pages/api/usage/hourly.ts +45 -0
  98. package/templates/shared/dashboard/src/pages/api/usage/projects.ts +51 -0
  99. package/templates/shared/dashboard/src/pages/api/user/identity.ts +11 -0
  100. package/templates/shared/dashboard/src/pages/settings/notifications.astro +34 -0
  101. package/templates/shared/dashboard/src/pages/settings/thresholds.astro +39 -0
  102. package/templates/shared/dashboard/src/pages/settings/usage.astro +28 -0
  103. package/templates/shared/docs/architecture.md +89 -0
  104. package/templates/shared/docs/post-deploy-runbook.md +126 -0
  105. package/templates/shared/docs/troubleshooting.md +91 -0
  106. package/templates/shared/package.json.hbs +5 -0
  107. package/templates/shared/scripts/ops/backfill-cloudflare-daily.ts +145 -0
  108. package/templates/shared/scripts/ops/backfill-monthly-rollups.ts +125 -0
  109. package/templates/shared/scripts/ops/validate-controls.js +141 -0
  110. package/templates/shared/tests/contract/validate-schemas.test.ts +130 -0
  111. package/templates/shared/tests/e2e/usage-api.test.ts +909 -0
  112. package/templates/shared/tests/fixtures/telemetry-envelope-invalid.json +9 -0
  113. package/templates/shared/tests/fixtures/telemetry-envelope-valid.json +27 -0
  114. package/templates/shared/tests/helpers/mock-d1.ts +61 -0
  115. package/templates/shared/tests/helpers/mock-kv.ts +37 -0
  116. package/templates/shared/tests/helpers/mock-storage.ts +166 -0
  117. package/templates/shared/tests/integration/kv-cache.test.ts +252 -0
  118. package/templates/shared/tests/integration/platform-usage.test.ts +956 -0
  119. package/templates/shared/tests/unit/billing.test.ts +331 -0
  120. package/templates/shared/tests/unit/cloudflare/graphql.test.ts +217 -0
  121. package/templates/shared/tests/unit/components/usage-transformers.test.ts +473 -0
  122. package/templates/shared/tests/unit/control.test.ts +226 -0
  123. package/templates/shared/tests/unit/cost-calculator.test.ts +141 -0
  124. package/templates/shared/tests/unit/economics.test.ts +365 -0
  125. package/templates/shared/tests/unit/telemetry-sampling.test.ts +401 -0
  126. package/templates/shared/tests/unit/workers/batch-persistence.test.ts +133 -0
  127. package/templates/shared/tests/unit/workers/budget-enforcement.test.ts +214 -0
  128. package/templates/shared/vitest.config.ts +18 -0
  129. package/templates/standard/dashboard/src/components/health/CircuitBreakerEvents.tsx +69 -0
  130. package/templates/standard/dashboard/src/components/health/CircuitBreakerPanel.tsx +97 -0
  131. package/templates/standard/dashboard/src/components/health/index.ts +2 -0
  132. package/templates/standard/dashboard/src/components/reports/CircuitBreakerReport.tsx +474 -0
  133. package/templates/standard/dashboard/src/components/reports/CostTrendsReport.tsx +229 -0
  134. package/templates/standard/dashboard/src/components/reports/ErrorTrendsReport.tsx +244 -0
  135. package/templates/standard/dashboard/src/components/reports/ProjectHealthTable.tsx +251 -0
  136. package/templates/standard/dashboard/src/components/reports/WarningDigestsTable.tsx +298 -0
  137. package/templates/standard/dashboard/src/components/usage/react/UsageTable.tsx +385 -0
  138. package/templates/standard/dashboard/src/components/usage/unified/CircuitBreakerEvents.tsx +305 -0
  139. package/templates/standard/dashboard/src/components/usage/unified/FeatureBudgets.tsx +472 -0
  140. package/templates/standard/dashboard/src/lib/errors/api.ts +84 -0
  141. package/templates/standard/dashboard/src/lib/errors/types.ts +75 -0
  142. package/templates/standard/dashboard/src/lib/infrastructure/api.ts +141 -0
  143. package/templates/standard/dashboard/src/lib/infrastructure/gatus.ts.hbs +112 -0
  144. package/templates/standard/dashboard/src/lib/services/proxy/index.ts +20 -0
  145. package/templates/standard/dashboard/src/lib/services/proxy/proxy.ts +244 -0
  146. package/templates/standard/dashboard/src/lib/services/proxy/types.ts +81 -0
  147. package/templates/standard/dashboard/src/pages/api/errors/[fingerprint]/mute.ts +49 -0
  148. package/templates/standard/dashboard/src/pages/api/errors/[fingerprint]/resolve.ts +36 -0
  149. package/templates/standard/dashboard/src/pages/api/errors/[fingerprint].ts +55 -0
  150. package/templates/standard/dashboard/src/pages/api/health/audit-history.ts +37 -0
  151. package/templates/standard/dashboard/src/pages/circuit-breakers.astro +13 -0
  152. package/templates/standard/tests/integration/platform-sentinel.test.ts +497 -0
  153. package/templates/standard/tests/unit/cloudflare/alerting.test.ts +480 -0
  154. package/templates/standard/tests/unit/error-collector/capture.test.ts +106 -0
  155. package/templates/standard/tests/unit/error-collector/dedup.test.ts +350 -0
  156. package/templates/standard/tests/unit/error-collector/fingerprint.test.ts +155 -0
  157. package/templates/standard/tests/unit/error-collector/github.test.ts +187 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Unified Observability Dashboard Components
3
+ *
4
+ * Barrel export for all unified dashboard components.
5
+ */
6
+
7
+ // Main orchestrator
8
+ export { UnifiedShell } from './UnifiedShell';
9
+ export { default as UnifiedShellDefault } from './UnifiedShell';
10
+
11
+ // Header
12
+ export { LiveHeader } from './LiveHeader';
13
+ export { default as LiveHeaderDefault } from './LiveHeader';
14
+
15
+ // Hero cards
16
+ export { HeroCardsRow } from './HeroCardsRow';
17
+ export { default as HeroCardsRowDefault } from './HeroCardsRow';
18
+
19
+ // Alert banner
20
+ export { AlertBanner } from './AlertBanner';
21
+ export { default as AlertBannerDefault } from './AlertBanner';
22
+
23
+ // Table components
24
+ export { ProjectsTable } from './ProjectsTable';
25
+ export { default as ProjectsTableDefault } from './ProjectsTable';
26
+
27
+ export { ResourceBreakdown } from './ResourceBreakdown';
28
+ export { default as ResourceBreakdownDefault } from './ResourceBreakdown';
29
+
30
+ // Utilities
31
+ export { Sparkline } from './Sparkline';
32
+ export { default as SparklineDefault } from './Sparkline';
33
+
34
+ {{#if isStandard}}
35
+ // Features tab components (standard tier)
36
+ export { FeatureBudgets } from './FeatureBudgets';
37
+ export { default as FeatureBudgetsDefault } from './FeatureBudgets';
38
+
39
+ export { CircuitBreakerEvents } from './CircuitBreakerEvents';
40
+ export { default as CircuitBreakerEventsDefault } from './CircuitBreakerEvents';
41
+ {{/if}}
42
+
43
+ {{#if isFull}}
44
+ // Recommendations (full tier)
45
+ export { Recommendations } from './Recommendations';
46
+ export { default as RecommendationsDefault } from './Recommendations';
47
+ {{/if}}
48
+
49
+ // Types
50
+ export * from './types';
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Unified Observability Dashboard Types
3
+ *
4
+ * Industrial Command Centre aesthetic - data-dense, monospace metrics
5
+ */
6
+
7
+ // ============================================================================
8
+ // Period & Tab Types
9
+ // ============================================================================
10
+
11
+ export type Period = '24h' | '7d' | '30d';
12
+ export type Tab = 'overview' | 'features';
13
+ export type SortField = 'name' | 'cost' | 'activity';
14
+ export type SortDir = 'asc' | 'desc';
15
+
16
+ // ============================================================================
17
+ // URL State
18
+ // ============================================================================
19
+
20
+ export interface URLState {
21
+ period: Period;
22
+ search: string;
23
+ sort: SortField;
24
+ dir: SortDir;
25
+ tab: Tab;
26
+ expanded: string[]; // project IDs
27
+ }
28
+
29
+ // ============================================================================
30
+ // Project Status & Health
31
+ // ============================================================================
32
+
33
+ export type OperationalStatus = 'RUN' | 'WARN' | 'STOP';
34
+ export type CircuitBreakerState = 'active' | 'tripped' | 'disabled';
35
+ export type HealthStatus = 'online' | 'idle' | 'unknown';
36
+
37
+ export interface ProjectStatus {
38
+ status: OperationalStatus;
39
+ spend: number;
40
+ cap: number;
41
+ percentage: number;
42
+ circuitBreaker: CircuitBreakerState;
43
+ lastSeen?: string; // ISO timestamp from heartbeat
44
+ }
45
+
46
+ // ============================================================================
47
+ // Hero Cards Data
48
+ // ============================================================================
49
+
50
+ export interface BurnRateData {
51
+ mtdCost: number;
52
+ mtdStartDate: string;
53
+ mtdEndDate: string;
54
+ projectedMonthlyCost: number;
55
+ dailyBurnRate: number;
56
+ daysIntoMonth: number;
57
+ daysRemaining: number;
58
+ confidence: 'low' | 'medium' | 'high';
59
+ vsLastMonthPct: number | null;
60
+ billingPeriodStart: string;
61
+ billingPeriodEnd: string;
62
+ status: 'green' | 'yellow' | 'red';
63
+ statusLabel: string;
64
+ statusDetail: string;
65
+ }
66
+
67
+ export interface ServiceUtilisation {
68
+ id: string;
69
+ label: string;
70
+ percentage: number;
71
+ current: number;
72
+ limit: number;
73
+ unit: string;
74
+ status: 'normal' | 'warning' | 'high' | 'critical' | 'overage';
75
+ costEstimate: number;
76
+ }
77
+
78
+ export interface UtilisationResponse {
79
+ success: boolean;
80
+ burnRate: BurnRateData;
81
+ cloudflareServices: ServiceUtilisation[];
82
+ projects: ProjectSummary[];
83
+ cached?: boolean;
84
+ }
85
+
86
+ // ============================================================================
87
+ // Project Data
88
+ // ============================================================================
89
+
90
+ export interface ProjectSummary {
91
+ projectId: string;
92
+ projectName: string;
93
+ primaryResource: string;
94
+ mtdCost: number;
95
+ costDeltaPct: number;
96
+ utilizationPct: number;
97
+ utilizationCurrent: number;
98
+ utilizationLimit: number;
99
+ utilizationUnit: string;
100
+ status: 'green' | 'yellow' | 'red';
101
+ sparklineData?: number[];
102
+ circuitBreakerStatus?: 'active' | 'tripped' | 'degraded';
103
+ repoUrl?: string;
104
+ }
105
+
106
+ export interface ProjectTableRow {
107
+ id: string;
108
+ name: string;
109
+ status: OperationalStatus;
110
+ mtdCost: number;
111
+ costDeltaPct: number;
112
+ activity: number;
113
+ activityTrend: number[]; // Last 6 data points for sparkline
114
+ circuitBreaker: CircuitBreakerState;
115
+ lastSeen?: string;
116
+ }
117
+
118
+ // ============================================================================
119
+ // Resource Breakdown (Lazy-loaded)
120
+ // ============================================================================
121
+
122
+ export type ResourceType =
123
+ | 'd1'
124
+ | 'kv'
125
+ | 'r2'
126
+ | 'vectorize'
127
+ | 'workers'
128
+ | 'durableObjects'
129
+ | 'queues'
130
+ | 'workersAI'
131
+ | 'pages';
132
+
133
+ /**
134
+ * Tool types for stacked bar chart (all 9 Cloudflare tools)
135
+ */
136
+ export type ToolType =
137
+ | 'workers'
138
+ | 'd1'
139
+ | 'kv'
140
+ | 'r2'
141
+ | 'vectorize'
142
+ | 'durableObjects'
143
+ | 'queues'
144
+ | 'workersAI'
145
+ | 'pages';
146
+
147
+ export interface ResourceMetric {
148
+ type: ResourceType;
149
+ label: string;
150
+ cost: number;
151
+ usage: number;
152
+ usageFormatted: string;
153
+ unit: string;
154
+ limit?: number;
155
+ limitPct?: number;
156
+ trend: number[]; // Last 6 data points for sparkline
157
+ }
158
+
159
+ export interface ProjectBreakdown {
160
+ projectId: string;
161
+ resources: ResourceMetric[];
162
+ totalCost: number;
163
+ fetchedAt: number; // timestamp for cache expiry
164
+ }
165
+
166
+ // ============================================================================
167
+ // Chart Data
168
+ // ============================================================================
169
+
170
+ export interface ChartDataPoint {
171
+ time: string;
172
+ timestamp: number;
173
+ d1: number;
174
+ kv: number;
175
+ workers: number;
176
+ r2: number;
177
+ vectorize: number;
178
+ durableObjects: number;
179
+ queues: number;
180
+ workersAI: number;
181
+ pages: number;
182
+ total: number;
183
+ }
184
+
185
+ export interface UsageRow {
186
+ time_bucket: string;
187
+ project_id: string;
188
+ d1_writes: number;
189
+ d1_reads: number;
190
+ kv_reads: number;
191
+ kv_writes: number;
192
+ workers_requests: number;
193
+ interaction_count: number;
194
+ }
195
+
196
+ // ============================================================================
197
+ // API Responses
198
+ // ============================================================================
199
+
200
+ export interface StatusResponse {
201
+ success: boolean;
202
+ projects: Record<string, ProjectStatus>;
203
+ timestamp: string;
204
+ }
205
+
206
+ export interface QueryResponse {
207
+ success: boolean;
208
+ data: UsageRow[];
209
+ }
210
+
211
+ export interface DailyResponse {
212
+ success: boolean;
213
+ data: ResourceMetric[];
214
+ }
215
+
216
+ /**
217
+ * Daily cost breakdown data from /api/usage/daily endpoint
218
+ */
219
+ export interface DailyCostBreakdown {
220
+ date: string;
221
+ workers: number;
222
+ d1: number;
223
+ kv: number;
224
+ r2: number;
225
+ durableObjects: number;
226
+ vectorize: number;
227
+ queues: number;
228
+ workersAI: number;
229
+ pages: number;
230
+ total: number;
231
+ }
232
+
233
+ export interface DailyCostTotals {
234
+ workers: number;
235
+ d1: number;
236
+ kv: number;
237
+ r2: number;
238
+ durableObjects: number;
239
+ vectorize: number;
240
+ queues: number;
241
+ workersAI: number;
242
+ pages: number;
243
+ total: number;
244
+ }
245
+
246
+ export interface DailyCostData {
247
+ days: DailyCostBreakdown[];
248
+ totals: DailyCostTotals;
249
+ period: {
250
+ start: string;
251
+ end: string;
252
+ };
253
+ }
254
+
255
+ // ============================================================================
256
+ // Billing Context (from /api/usage/billing-context)
257
+ // ============================================================================
258
+
259
+ export interface BillingPeriod {
260
+ startDate: string; // ISO date
261
+ endDate: string; // ISO date
262
+ daysInPeriod: number;
263
+ daysElapsed: number;
264
+ daysRemaining: number;
265
+ progress: number; // 0-1
266
+ }
267
+
268
+ export interface ServiceAllowance {
269
+ monthly: number;
270
+ prorated: number;
271
+ unit: string;
272
+ isPaidPlan: boolean;
273
+ }
274
+
275
+ export type PlanType = 'free' | 'paid' | 'enterprise';
276
+
277
+ export interface BillingContextResponse {
278
+ success: boolean;
279
+ billingPeriod: BillingPeriod;
280
+ planType: PlanType;
281
+ allowances: Record<ToolType, ServiceAllowance>;
282
+ periodFormatted: string;
283
+ countdownText: string;
284
+ prorationFactors: {
285
+ '24h': number;
286
+ '7d': number;
287
+ '30d': number;
288
+ };
289
+ timestamp: string;
290
+ }
291
+
292
+ // ============================================================================
293
+ // Granular Usage (from /api/usage/granular)
294
+ // ============================================================================
295
+
296
+ export interface DailyToolUsage {
297
+ date: string; // ISO date (YYYY-MM-DD)
298
+ workers: number;
299
+ d1: number;
300
+ kv: number;
301
+ r2: number;
302
+ vectorize: number;
303
+ durableObjects: number;
304
+ queues: number;
305
+ workersAI: number;
306
+ pages: number;
307
+ total: number;
308
+ }
309
+
310
+ export interface ProjectResourceBreakdown {
311
+ resourceType: ToolType;
312
+ usage: number;
313
+ cost: number;
314
+ unit: string;
315
+ isCostDriver: boolean; // True for top 3 costs in project
316
+ }
317
+
318
+ export interface ProjectUsageSummary {
319
+ project: string;
320
+ totalRequests: number;
321
+ totalCost: number;
322
+ resources: ProjectResourceBreakdown[];
323
+ topCostDrivers: ToolType[]; // Top 3 cost driver tool types
324
+ }
325
+
326
+ export interface GranularResponse {
327
+ success: boolean;
328
+ period: {
329
+ start: string;
330
+ end: string;
331
+ days: number;
332
+ };
333
+ byDate: DailyToolUsage[];
334
+ byProject: ProjectUsageSummary[];
335
+ totals: {
336
+ requests: number;
337
+ cost: number;
338
+ byTool: Record<ToolType, { requests: number; cost: number }>;
339
+ };
340
+ timestamp: string;
341
+ }
342
+
343
+ // ============================================================================
344
+ // Colour Configuration
345
+ // ============================================================================
346
+
347
+ export const STATUS_COLORS: Record<OperationalStatus, { bg: string; text: string; glow: string }> =
348
+ {
349
+ RUN: {
350
+ bg: 'bg-emerald-500/20',
351
+ text: 'text-emerald-400',
352
+ glow: 'shadow-emerald-500/20',
353
+ },
354
+ WARN: {
355
+ bg: 'bg-amber-500/20',
356
+ text: 'text-amber-400',
357
+ glow: 'shadow-amber-500/20',
358
+ },
359
+ STOP: {
360
+ bg: 'bg-rose-500/20',
361
+ text: 'text-rose-400',
362
+ glow: 'shadow-rose-500/20',
363
+ },
364
+ };
365
+
366
+ export const CB_COLORS: Record<CircuitBreakerState, string> = {
367
+ active: 'bg-emerald-500',
368
+ tripped: 'bg-rose-500',
369
+ disabled: 'bg-slate-500',
370
+ };
371
+
372
+ export const HEALTH_COLORS: Record<HealthStatus, { dot: string; text: string }> = {
373
+ online: { dot: 'bg-emerald-500', text: 'text-emerald-400' },
374
+ idle: { dot: 'bg-amber-500', text: 'text-amber-400' },
375
+ unknown: { dot: 'bg-slate-500', text: 'text-slate-500' },
376
+ };
377
+
378
+ export const RESOURCE_COLORS: Record<ResourceType, { bg: string; stroke: string }> = {
379
+ d1: { bg: 'rgba(59, 130, 246, 0.3)', stroke: '#3b82f6' }, // Blue
380
+ kv: { bg: 'rgba(139, 92, 246, 0.3)', stroke: '#8b5cf6' }, // Purple
381
+ r2: { bg: 'rgba(16, 185, 129, 0.3)', stroke: '#10b981' }, // Green
382
+ vectorize: { bg: 'rgba(236, 72, 153, 0.3)', stroke: '#ec4899' }, // Pink
383
+ workers: { bg: 'rgba(249, 115, 22, 0.3)', stroke: '#f97316' }, // Orange
384
+ durableObjects: { bg: 'rgba(99, 102, 241, 0.3)', stroke: '#6366f1' }, // Indigo
385
+ queues: { bg: 'rgba(20, 184, 166, 0.3)', stroke: '#14b8a6' }, // Teal
386
+ workersAI: { bg: 'rgba(245, 158, 11, 0.3)', stroke: '#f59e0b' }, // Amber
387
+ pages: { bg: 'rgba(132, 204, 22, 0.3)', stroke: '#84cc16' }, // Lime
388
+ };
389
+
390
+ export const RESOURCE_LABELS: Record<ResourceType, string> = {
391
+ d1: 'D1',
392
+ kv: 'KV',
393
+ r2: 'R2',
394
+ vectorize: 'Vectorize',
395
+ workers: 'Workers',
396
+ durableObjects: 'Durable Objects',
397
+ queues: 'Queues',
398
+ workersAI: 'Workers AI',
399
+ pages: 'Pages',
400
+ };
401
+
402
+ /**
403
+ * Tool configuration for stacked bar chart
404
+ * Includes color, label, and sort order
405
+ */
406
+ export const TOOL_CONFIG: Record<ToolType, { color: string; label: string; order: number }> = {
407
+ workers: { color: '#F97316', label: 'Workers', order: 1 },
408
+ d1: { color: '#3B82F6', label: 'D1', order: 2 },
409
+ kv: { color: '#8B5CF6', label: 'KV', order: 3 },
410
+ r2: { color: '#10B981', label: 'R2', order: 4 },
411
+ vectorize: { color: '#EC4899', label: 'Vectorize', order: 5 },
412
+ durableObjects: { color: '#6366F1', label: 'Durable Objects', order: 6 },
413
+ queues: { color: '#14B8A6', label: 'Queues', order: 7 },
414
+ workersAI: { color: '#F59E0B', label: 'Workers AI', order: 8 },
415
+ pages: { color: '#84CC16', label: 'Pages', order: 9 },
416
+ };