@littlebearapps/platform-admin-sdk 1.4.2 → 1.5.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 (111) hide show
  1. package/dist/templates.d.ts +1 -1
  2. package/dist/templates.js +121 -2
  3. package/package.json +1 -1
  4. package/templates/full/config/audit-targets.yaml +72 -0
  5. package/templates/full/dashboard/src/components/notifications/NotificationBell.tsx +30 -0
  6. package/templates/full/dashboard/src/components/notifications/NotificationList.tsx +116 -0
  7. package/templates/full/dashboard/src/components/notifications/index.ts +2 -0
  8. package/templates/full/dashboard/src/components/patterns/PatternStats.tsx +60 -0
  9. package/templates/full/dashboard/src/components/patterns/SuggestionsQueue.tsx +115 -0
  10. package/templates/full/dashboard/src/components/patterns/index.ts +2 -0
  11. package/templates/full/dashboard/src/components/search/SearchModal.tsx +108 -0
  12. package/templates/full/dashboard/src/pages/api/notifications/index.ts +47 -0
  13. package/templates/full/dashboard/src/pages/api/notifications/unread-count.ts +31 -0
  14. package/templates/full/dashboard/src/pages/api/patterns/approve.ts +55 -0
  15. package/templates/full/dashboard/src/pages/api/patterns/index.ts +36 -0
  16. package/templates/full/dashboard/src/pages/api/patterns/reject.ts +54 -0
  17. package/templates/full/dashboard/src/pages/api/search/index.ts +74 -0
  18. package/templates/full/dashboard/src/pages/notifications.astro +11 -0
  19. package/templates/full/migrations/008_auditor.sql +99 -0
  20. package/templates/full/migrations/010_pricing_versions.sql +110 -0
  21. package/templates/full/migrations/011_multi_account.sql +51 -0
  22. package/templates/full/scripts/ops/set-kv-pricing.ts +182 -0
  23. package/templates/full/workers/lib/ai-judge-schema.ts +181 -0
  24. package/templates/full/workers/lib/auditor/comprehensive-report.ts +407 -0
  25. package/templates/full/workers/lib/auditor/feature-coverage.ts +348 -0
  26. package/templates/full/workers/lib/auditor/index.ts +9 -0
  27. package/templates/full/workers/lib/auditor/types.ts +167 -0
  28. package/templates/full/workers/platform-auditor.ts +1071 -0
  29. package/templates/full/wrangler.auditor.jsonc.hbs +75 -0
  30. package/templates/shared/.github/workflows/platform-check.yml.hbs +28 -0
  31. package/templates/shared/config/observability.yaml.hbs +276 -0
  32. package/templates/shared/contracts/schemas/envelope.v1.schema.json +64 -0
  33. package/templates/shared/contracts/schemas/error_report.v1.schema.json +65 -0
  34. package/templates/shared/contracts/types/telemetry-envelope.types.ts +139 -0
  35. package/templates/shared/dashboard/astro.config.mjs +21 -0
  36. package/templates/shared/dashboard/package.json.hbs +29 -0
  37. package/templates/shared/dashboard/src/components/Header.astro +29 -0
  38. package/templates/shared/dashboard/src/components/Nav.astro.hbs +57 -0
  39. package/templates/shared/dashboard/src/components/overview/ActivityFeed.tsx +134 -0
  40. package/templates/shared/dashboard/src/components/overview/CostQuadrant.tsx +131 -0
  41. package/templates/shared/dashboard/src/components/overview/ErrorsQuadrant.tsx +113 -0
  42. package/templates/shared/dashboard/src/components/overview/HealthQuadrant.tsx +87 -0
  43. package/templates/shared/dashboard/src/components/overview/MissionControl.tsx +139 -0
  44. package/templates/shared/dashboard/src/components/resources/AllowanceStatus.tsx +44 -0
  45. package/templates/shared/dashboard/src/components/resources/CostCentreOverview.tsx +42 -0
  46. package/templates/shared/dashboard/src/components/resources/ResourceTabs.tsx +69 -0
  47. package/templates/shared/dashboard/src/components/resources/index.ts +3 -0
  48. package/templates/shared/dashboard/src/components/settings/SettingsCard.tsx +21 -0
  49. package/templates/shared/dashboard/src/components/settings/index.ts +1 -0
  50. package/templates/shared/dashboard/src/components/ui/AlertBanner.tsx +39 -0
  51. package/templates/shared/dashboard/src/components/ui/Sparkline.tsx +127 -0
  52. package/templates/shared/dashboard/src/components/ui/StatusDot.tsx +21 -0
  53. package/templates/shared/dashboard/src/components/ui/index.ts +3 -0
  54. package/templates/shared/dashboard/src/env.d.ts.hbs +34 -0
  55. package/templates/shared/dashboard/src/layouts/DashboardLayout.astro +37 -0
  56. package/templates/shared/dashboard/src/lib/fetch.ts +29 -0
  57. package/templates/shared/dashboard/src/lib/types.ts +72 -0
  58. package/templates/shared/dashboard/src/middleware/auth.ts +100 -0
  59. package/templates/shared/dashboard/src/middleware/index.ts +1 -0
  60. package/templates/shared/dashboard/src/pages/api/overview/summary.ts +311 -0
  61. package/templates/shared/dashboard/src/pages/api/usage/circuit-breakers.ts +44 -0
  62. package/templates/shared/dashboard/src/pages/api/usage/status.ts +42 -0
  63. package/templates/shared/dashboard/src/pages/dashboard.astro +11 -0
  64. package/templates/shared/dashboard/src/pages/index.astro +3 -0
  65. package/templates/shared/dashboard/src/pages/resources.astro +11 -0
  66. package/templates/shared/dashboard/src/pages/settings/index.astro +28 -0
  67. package/templates/shared/dashboard/src/styles/global.css +29 -0
  68. package/templates/shared/dashboard/tailwind.config.mjs +9 -0
  69. package/templates/shared/dashboard/tsconfig.json +9 -0
  70. package/templates/shared/dashboard/wrangler.json.hbs +47 -0
  71. package/templates/shared/package.json.hbs +12 -1
  72. package/templates/shared/scripts/ops/backfill-cloudflare-hourly.ts +473 -0
  73. package/templates/shared/scripts/ops/discover-graphql-datasets.ts +482 -0
  74. package/templates/shared/scripts/ops/reset-budget-state.ts +279 -0
  75. package/templates/shared/scripts/ops/validate-pipeline.ts +237 -0
  76. package/templates/shared/scripts/ops/verify-account-completeness.ts +236 -0
  77. package/templates/shared/scripts/validate-schemas.js +61 -0
  78. package/templates/shared/workers/lib/usage/collectors/anthropic.ts +114 -0
  79. package/templates/shared/workers/lib/usage/collectors/apify.ts +96 -0
  80. package/templates/shared/workers/lib/usage/collectors/custom-http.ts +151 -0
  81. package/templates/shared/workers/lib/usage/collectors/deepseek.ts +92 -0
  82. package/templates/shared/workers/lib/usage/collectors/gemini.ts +263 -0
  83. package/templates/shared/workers/lib/usage/collectors/github.ts +362 -0
  84. package/templates/shared/workers/lib/usage/collectors/index.ts +31 -15
  85. package/templates/shared/workers/lib/usage/collectors/minimax.ts +106 -0
  86. package/templates/shared/workers/lib/usage/collectors/openai.ts +171 -0
  87. package/templates/shared/workers/lib/usage/collectors/resend.ts +79 -0
  88. package/templates/shared/workers/lib/usage/collectors/stripe.ts +192 -0
  89. package/templates/shared/workers/lib/usage/shared/types.ts +46 -0
  90. package/templates/shared/workers/platform-usage.ts +98 -8
  91. package/templates/standard/dashboard/src/components/errors/ErrorStats.tsx +53 -0
  92. package/templates/standard/dashboard/src/components/errors/ErrorsTable.tsx +133 -0
  93. package/templates/standard/dashboard/src/components/errors/index.ts +2 -0
  94. package/templates/standard/dashboard/src/components/health/DlqStatusCard.tsx +52 -0
  95. package/templates/standard/dashboard/src/components/health/HealthTabs.tsx +86 -0
  96. package/templates/standard/dashboard/src/components/health/index.ts +2 -0
  97. package/templates/standard/dashboard/src/lib/errors.ts +28 -0
  98. package/templates/standard/dashboard/src/pages/api/errors/index.ts +58 -0
  99. package/templates/standard/dashboard/src/pages/api/errors/stats.ts +55 -0
  100. package/templates/standard/dashboard/src/pages/api/health/dlq.ts +43 -0
  101. package/templates/standard/dashboard/src/pages/errors.astro +13 -0
  102. package/templates/standard/dashboard/src/pages/health.astro +11 -0
  103. package/templates/standard/migrations/009_topology_mapper.sql +65 -0
  104. package/templates/standard/workers/lib/error-collector/email-health-alerts.ts +37 -3
  105. package/templates/standard/workers/lib/error-collector/gap-alerts.ts +32 -1
  106. package/templates/standard/workers/lib/mapper/attribution-check.ts +339 -0
  107. package/templates/standard/workers/lib/mapper/index.ts +7 -0
  108. package/templates/standard/workers/platform-mapper.ts +482 -0
  109. package/templates/standard/workers/platform-sdk-test-client.ts +125 -0
  110. package/templates/standard/wrangler.mapper.jsonc.hbs +85 -0
  111. package/templates/standard/wrangler.sdk-test-client.jsonc.hbs +62 -0
@@ -0,0 +1,75 @@
1
+ {
2
+ "$schema": "./node_modules/wrangler/config-schema.json",
3
+ "name": "{{projectSlug}}-auditor",
4
+ "main": "workers/platform-auditor.ts",
5
+ "compatibility_date": "2026-01-01",
6
+ "compatibility_flags": ["nodejs_compat_v2"],
7
+
8
+ "observability": {
9
+ "enabled": true,
10
+ "logs": {
11
+ "enabled": true,
12
+ "sampling_rate": 1,
13
+ "invocation_logs": true
14
+ },
15
+ "traces": {
16
+ "enabled": true,
17
+ "head_sampling_rate": 0.1
18
+ }
19
+ },
20
+ "upload_source_maps": true,
21
+
22
+ "triggers": {
23
+ "crons": [
24
+ "0 0 * * SUN",
25
+ "0 0 * * WED"
26
+ ]
27
+ },
28
+
29
+ "d1_databases": [
30
+ {
31
+ "binding": "PLATFORM_DB",
32
+ "database_name": "{{projectSlug}}-metrics",
33
+ "database_id": "YOUR_D1_DATABASE_ID",
34
+ "migrations_dir": "storage/d1/migrations"
35
+ }
36
+ ],
37
+
38
+ "kv_namespaces": [
39
+ {
40
+ "binding": "PLATFORM_CACHE",
41
+ "id": "YOUR_KV_NAMESPACE_ID"
42
+ }
43
+ ],
44
+
45
+ "queues": {
46
+ "producers": [
47
+ {
48
+ "binding": "PLATFORM_TELEMETRY",
49
+ "queue": "{{projectSlug}}-telemetry"
50
+ }
51
+ ]
52
+ },
53
+
54
+ "services": [
55
+ {
56
+ "binding": "ALERT_ROUTER",
57
+ "service": "{{projectSlug}}-alert-router"
58
+ }
59
+ ],
60
+
61
+ "ai": {
62
+ "binding": "AI"
63
+ },
64
+
65
+ "vars": {
66
+ "CLOUDFLARE_ACCOUNT_ID": "YOUR_ACCOUNT_ID",
67
+ "GATUS_HEARTBEAT_URL": ""
68
+ },
69
+
70
+ "tail_consumers": [
71
+ {
72
+ "service": "{{projectSlug}}-error-collector"
73
+ }
74
+ ]
75
+ }
@@ -0,0 +1,28 @@
1
+ # Platform SDK Integration Check
2
+ #
3
+ # Validates Platform SDK usage, wrangler configs, and cost safety patterns.
4
+ # Uses the reusable workflow from the Platform SDKs repository.
5
+ #
6
+ # Checks performed:
7
+ # - SDK installation and version
8
+ # - Wrangler configs (PLATFORM_CACHE, telemetry queue, observability, tail_consumers)
9
+ # - Budget wrappers (withFeatureBudget, withCronBudget, withQueueBudget)
10
+ # - Feature ID format (project:category:feature)
11
+ # - CircuitBreakerError handling
12
+ # - Cost safety (D1 batch writes, ON CONFLICT, SELECT LIMIT, no SQL injection)
13
+ #
14
+ # See: https://github.com/littlebearapps/platform-sdks
15
+
16
+ name: Platform SDK Check
17
+
18
+ on:
19
+ push:
20
+ branches: [main]
21
+ pull_request:
22
+ branches: [main]
23
+
24
+ jobs:
25
+ sdk-check:
26
+ uses: littlebearapps/platform-sdks/.github/workflows/consumer-check.yml@main
27
+ with:
28
+ project-name: {{projectSlug}}
@@ -0,0 +1,276 @@
1
+ # Observability Configuration
2
+ #
3
+ # Single Source of Truth for Workers observability standards.
4
+ # Defines sampling rates, logging patterns, and audit criteria.
5
+ #
6
+ # Used by:
7
+ # - platform-auditor: Reference standard for audits (Full tier)
8
+ # - AI Judge: Audit checklist and scoring rubrics (Full tier)
9
+ # - Developers: Reference for wrangler config settings
10
+ #
11
+ # Version: 1.0.0
12
+
13
+ metadata:
14
+ version: "1.0.0"
15
+ lastUpdated: "{{currentDate}}"
16
+ linkedRegistry: "./services.yaml"
17
+
18
+ # ============================================================
19
+ # GLOBAL STANDARDS (Required for ALL workers)
20
+ # ============================================================
21
+ # These settings must be present in every wrangler config
22
+ # ============================================================
23
+
24
+ standards:
25
+ # Source maps - ALWAYS required for readable stack traces
26
+ source_maps:
27
+ required: true
28
+ setting: "upload_source_maps"
29
+ value: true
30
+ severity: critical
31
+ rationale: "Essential for debugging production errors"
32
+
33
+ # Observability block - ALWAYS required
34
+ observability:
35
+ required: true
36
+ setting: "observability.enabled"
37
+ value: true
38
+ severity: critical
39
+ rationale: "Base requirement for all logging and tracing"
40
+
41
+ # Logs - ALWAYS required
42
+ logs:
43
+ required: true
44
+ settings:
45
+ enabled: true
46
+ invocation_logs: true
47
+ severity: critical
48
+ rationale: "Essential for debugging and monitoring"
49
+
50
+ # Traces - Recommended (beta but valuable)
51
+ traces:
52
+ required: false
53
+ recommended: true
54
+ settings:
55
+ enabled: true
56
+ severity: high
57
+ rationale: "Automatic instrumentation for performance debugging"
58
+
59
+ # ============================================================
60
+ # SAMPLING RATE PROFILES
61
+ # ============================================================
62
+ # Profiles based on worker characteristics.
63
+ # Assign a profile to each worker in the projects section below.
64
+ # ============================================================
65
+
66
+ sampling_profiles:
67
+ # Critical path workers (auth, payments, etc.)
68
+ critical:
69
+ logs:
70
+ head_sampling_rate: 1.0 # 100% - never miss errors
71
+ traces:
72
+ head_sampling_rate: 0.5 # 50% - high visibility
73
+ applies_to:
74
+ - "workers with auth responsibilities"
75
+ - "workers handling payments"
76
+ - "workers with revenue impact"
77
+
78
+ # Low traffic workers (<1K requests/day)
79
+ low_traffic:
80
+ logs:
81
+ head_sampling_rate: 1.0 # 100%
82
+ traces:
83
+ head_sampling_rate: 1.0 # 100%
84
+ applies_to:
85
+ - "scheduled/cron workers"
86
+ - "admin/internal tools"
87
+ - "audit workers"
88
+
89
+ # Medium traffic workers (1K-100K requests/day)
90
+ medium_traffic:
91
+ logs:
92
+ head_sampling_rate: 0.5 # 50%
93
+ traces:
94
+ head_sampling_rate: 0.1 # 10%
95
+ applies_to:
96
+ - "API endpoints with moderate traffic"
97
+ - "dashboard workers"
98
+
99
+ # High traffic workers (>100K requests/day)
100
+ high_traffic:
101
+ logs:
102
+ head_sampling_rate: 0.1 # 10%
103
+ traces:
104
+ head_sampling_rate: 0.05 # 5%
105
+ applies_to:
106
+ - "public API endpoints"
107
+ - "high-volume queue consumers"
108
+
109
+ # Staging/Development (always full visibility)
110
+ staging:
111
+ logs:
112
+ head_sampling_rate: 1.0 # 100%
113
+ traces:
114
+ head_sampling_rate: 1.0 # 100%
115
+ applies_to:
116
+ - "any worker in staging environment"
117
+ - "test workers"
118
+
119
+ # ============================================================
120
+ # PROJECT OBSERVABILITY SETTINGS
121
+ # ============================================================
122
+
123
+ projects:
124
+ {{projectSlug}}:
125
+ status: pending # Update to 'compliant' after verification
126
+ profile: low_traffic
127
+ workers:
128
+ {{projectSlug}}-usage:
129
+ profile: medium_traffic
130
+ sampling:
131
+ logs: { head_sampling_rate: 1.0 }
132
+ traces: { head_sampling_rate: 0.1 }
133
+ notes: "Central data warehouse — full logging essential"
134
+
135
+ {{#if isStandard}}
136
+ {{projectSlug}}-error-collector:
137
+ profile: low_traffic
138
+ sampling:
139
+ logs: { head_sampling_rate: 1.0 }
140
+ traces: { head_sampling_rate: 0.5 }
141
+ notes: "Tail worker — captures all error outcomes"
142
+
143
+ {{projectSlug}}-sentinel:
144
+ profile: low_traffic
145
+ sampling:
146
+ logs: { head_sampling_rate: 1.0 }
147
+ traces: { head_sampling_rate: 0.5 }
148
+ notes: "Gap detection and cost monitoring"
149
+
150
+ {{projectSlug}}-mapper:
151
+ profile: low_traffic
152
+ sampling:
153
+ logs: { head_sampling_rate: 1.0 }
154
+ traces: { head_sampling_rate: 0.5 }
155
+ notes: "Resource topology mapping"
156
+
157
+ {{projectSlug}}-sdk-test-client:
158
+ profile: staging
159
+ optional: true
160
+ notes: "SDK validation — on-demand only"
161
+ {{/if}}
162
+
163
+ {{#if isFull}}
164
+ {{projectSlug}}-pattern-discovery:
165
+ profile: low_traffic
166
+ sampling:
167
+ logs: { head_sampling_rate: 1.0 }
168
+ traces: { head_sampling_rate: 1.0 }
169
+ notes: "Daily AI discovery cron — full visibility"
170
+
171
+ {{projectSlug}}-alert-router:
172
+ profile: critical
173
+ sampling:
174
+ logs: { head_sampling_rate: 1.0 }
175
+ traces: { head_sampling_rate: 0.5 }
176
+ notes: "Critical — routes all alerts"
177
+
178
+ {{projectSlug}}-auditor:
179
+ profile: low_traffic
180
+ sampling:
181
+ logs: { head_sampling_rate: 1.0 }
182
+ traces: { head_sampling_rate: 1.0 }
183
+ notes: "Weekly cron — full visibility always"
184
+ {{/if}}
185
+
186
+ # ============================================================
187
+ # STRUCTURED LOGGING SCHEMA
188
+ # ============================================================
189
+ # Standard fields for console.log() JSON objects.
190
+ # Use the Platform SDK createLogger() for automatic formatting.
191
+ # ============================================================
192
+
193
+ logging_schema:
194
+ required_fields:
195
+ - name: event
196
+ type: string
197
+ description: "Event type (e.g., 'api_request', 'db_query', 'error')"
198
+
199
+ recommended_fields:
200
+ - name: requestId
201
+ type: string
202
+ description: "CF ray ID or custom request ID"
203
+ source: "request.headers.get('cf-ray')"
204
+
205
+ - name: projectId
206
+ type: string
207
+ description: "Project identifier"
208
+
209
+ - name: featureId
210
+ type: string
211
+ description: "Feature being used (matches services.yaml)"
212
+
213
+ - name: durationMs
214
+ type: number
215
+ description: "Operation duration in milliseconds"
216
+
217
+ error_fields:
218
+ - name: error.message
219
+ type: string
220
+ required: true
221
+
222
+ - name: error.name
223
+ type: string
224
+ required: true
225
+
226
+ - name: error.stack
227
+ type: string
228
+ required: false
229
+
230
+ # ============================================================
231
+ # AUDIT CHECKLIST
232
+ # ============================================================
233
+ # Items verified by AI Judge for observability audits (Full tier).
234
+ # Severity: critical (must fix), high (should fix), medium (nice to have)
235
+ # ============================================================
236
+
237
+ audit_checklist:
238
+ - id: source_maps_enabled
239
+ check: "upload_source_maps === true"
240
+ severity: critical
241
+ message: "Source maps must be enabled for readable stack traces"
242
+
243
+ - id: observability_enabled
244
+ check: "observability.enabled === true"
245
+ severity: critical
246
+ message: "Observability must be enabled"
247
+
248
+ - id: logs_enabled
249
+ check: "observability.logs.enabled === true"
250
+ severity: critical
251
+ message: "Logs must be enabled"
252
+
253
+ - id: traces_enabled
254
+ check: "observability.traces.enabled === true"
255
+ severity: high
256
+ message: "Traces should be enabled for automatic instrumentation"
257
+
258
+ - id: sampling_rate_appropriate
259
+ check: "sampling rate matches traffic profile"
260
+ severity: medium
261
+ message: "Sampling rate should match worker traffic level"
262
+
263
+ - id: structured_logging_used
264
+ check: "console.log uses JSON objects, not string interpolation"
265
+ severity: medium
266
+ message: "Use structured JSON logging for queryability"
267
+
268
+ - id: error_context_included
269
+ check: "error logs include requestId and relevant context"
270
+ severity: medium
271
+ message: "Error logs should include request context for debugging"
272
+
273
+ - id: invocation_logs_enabled
274
+ check: "observability.logs.invocation_logs !== false"
275
+ severity: low
276
+ message: "Invocation logs provide request/response metadata"
@@ -0,0 +1,64 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "envelope.v1.schema.json",
4
+ "title": "Telemetry Message Envelope v1",
5
+ "description": "Standard envelope for Platform SDK telemetry messages sent via queue",
6
+ "type": "object",
7
+ "required": ["feature_key", "project", "category", "feature", "metrics", "timestamp"],
8
+ "properties": {
9
+ "feature_key": {
10
+ "type": "string",
11
+ "description": "Fully qualified feature key (project:category:feature)",
12
+ "pattern": "^[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+$"
13
+ },
14
+ "project": {
15
+ "type": "string",
16
+ "description": "Project identifier",
17
+ "minLength": 1
18
+ },
19
+ "category": {
20
+ "type": "string",
21
+ "description": "Feature category within the project",
22
+ "minLength": 1
23
+ },
24
+ "feature": {
25
+ "type": "string",
26
+ "description": "Feature name within the category",
27
+ "minLength": 1
28
+ },
29
+ "metrics": {
30
+ "type": "object",
31
+ "description": "Feature metrics payload (FeatureMetrics type from consumer SDK)",
32
+ "properties": {
33
+ "d1Writes": { "type": "number", "minimum": 0 },
34
+ "d1Reads": { "type": "number", "minimum": 0 },
35
+ "d1RowsRead": { "type": "number", "minimum": 0 },
36
+ "d1RowsWritten": { "type": "number", "minimum": 0 },
37
+ "kvReads": { "type": "number", "minimum": 0 },
38
+ "kvWrites": { "type": "number", "minimum": 0 },
39
+ "kvDeletes": { "type": "number", "minimum": 0 },
40
+ "kvLists": { "type": "number", "minimum": 0 },
41
+ "aiRequests": { "type": "number", "minimum": 0 },
42
+ "aiNeurons": { "type": "number", "minimum": 0 },
43
+ "vectorizeQueries": { "type": "number", "minimum": 0 },
44
+ "vectorizeInserts": { "type": "number", "minimum": 0 },
45
+ "doRequests": { "type": "number", "minimum": 0 },
46
+ "doGbSeconds": { "type": "number", "minimum": 0 },
47
+ "r2ClassA": { "type": "number", "minimum": 0 },
48
+ "r2ClassB": { "type": "number", "minimum": 0 },
49
+ "queueMessages": { "type": "number", "minimum": 0 },
50
+ "requests": { "type": "number", "minimum": 0 },
51
+ "cpuMs": { "type": "number", "minimum": 0 }
52
+ },
53
+ "additionalProperties": false
54
+ },
55
+ "timestamp": {
56
+ "type": "number",
57
+ "description": "Unix timestamp in milliseconds when the event occurred"
58
+ },
59
+ "is_heartbeat": {
60
+ "type": "boolean",
61
+ "description": "If true, this is a heartbeat message (no metrics, just liveness)"
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "error_report.v1.schema.json",
4
+ "title": "Error Report v1",
5
+ "description": "Error report captured by the error-collector tail worker",
6
+ "type": "object",
7
+ "required": ["script_name", "fingerprint", "message"],
8
+ "properties": {
9
+ "script_name": {
10
+ "type": "string",
11
+ "description": "Name of the worker that produced the error",
12
+ "minLength": 1
13
+ },
14
+ "fingerprint": {
15
+ "type": "string",
16
+ "description": "Unique error identifier for deduplication (SHA-256 hash of normalised message + script)",
17
+ "minLength": 1
18
+ },
19
+ "message": {
20
+ "type": "string",
21
+ "description": "Error message text",
22
+ "minLength": 1
23
+ },
24
+ "stack_trace": {
25
+ "type": "string",
26
+ "description": "Full stack trace if available"
27
+ },
28
+ "outcome": {
29
+ "type": "string",
30
+ "description": "Worker outcome type",
31
+ "enum": [
32
+ "exception",
33
+ "exceededCpu",
34
+ "exceededMemory",
35
+ "canceled",
36
+ "responseStreamDisconnected",
37
+ "scriptNotFound",
38
+ "soft_error",
39
+ "warning"
40
+ ]
41
+ },
42
+ "priority": {
43
+ "type": "string",
44
+ "description": "Assigned priority level",
45
+ "enum": ["P0", "P1", "P2", "P3", "P4"]
46
+ },
47
+ "category": {
48
+ "type": "string",
49
+ "description": "Error category (e.g., unhandled-exception, quota-exhausted, rate-limited)"
50
+ },
51
+ "project": {
52
+ "type": "string",
53
+ "description": "Project the error belongs to (resolved from SCRIPT_MAP KV)"
54
+ },
55
+ "timestamp": {
56
+ "type": "string",
57
+ "format": "date-time",
58
+ "description": "When the error occurred (ISO 8601 UTC)"
59
+ },
60
+ "event_timestamp": {
61
+ "type": "number",
62
+ "description": "Unix timestamp in milliseconds from the tail event"
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Telemetry Envelope Types
3
+ *
4
+ * TypeScript interfaces for Platform SDK telemetry messages and error reports.
5
+ * These types mirror the JSON schemas in contracts/schemas/ and provide
6
+ * compile-time type safety.
7
+ *
8
+ * @see contracts/schemas/envelope.v1.schema.json
9
+ * @see contracts/schemas/error_report.v1.schema.json
10
+ */
11
+
12
+ // =============================================================================
13
+ // Telemetry Message Types
14
+ // =============================================================================
15
+
16
+ /**
17
+ * Feature metrics payload — maps to FeatureMetrics from consumer SDK.
18
+ * Each field corresponds to a Cloudflare service metric.
19
+ */
20
+ export interface TelemetryMetrics {
21
+ // D1 Database
22
+ d1Writes?: number;
23
+ d1Reads?: number;
24
+ d1RowsRead?: number;
25
+ d1RowsWritten?: number;
26
+
27
+ // KV Namespace
28
+ kvReads?: number;
29
+ kvWrites?: number;
30
+ kvDeletes?: number;
31
+ kvLists?: number;
32
+
33
+ // Workers AI
34
+ aiRequests?: number;
35
+ aiNeurons?: number;
36
+
37
+ // Vectorize
38
+ vectorizeQueries?: number;
39
+ vectorizeInserts?: number;
40
+
41
+ // Durable Objects
42
+ doRequests?: number;
43
+ doGbSeconds?: number;
44
+
45
+ // R2 Storage
46
+ r2ClassA?: number;
47
+ r2ClassB?: number;
48
+
49
+ // Queues
50
+ queueMessages?: number;
51
+
52
+ // General
53
+ requests?: number;
54
+ cpuMs?: number;
55
+ }
56
+
57
+ /**
58
+ * Telemetry message envelope — the standard format for SDK telemetry
59
+ * sent through the platform-telemetry queue.
60
+ */
61
+ export interface TelemetryEnvelope {
62
+ /** Fully qualified feature key (project:category:feature) */
63
+ feature_key: string;
64
+ /** Project identifier */
65
+ project: string;
66
+ /** Feature category within the project */
67
+ category: string;
68
+ /** Feature name within the category */
69
+ feature: string;
70
+ /** Feature metrics payload */
71
+ metrics: TelemetryMetrics;
72
+ /** Unix timestamp in milliseconds when the event occurred */
73
+ timestamp: number;
74
+ /** If true, this is a heartbeat message (no metrics, just liveness) */
75
+ is_heartbeat?: boolean;
76
+ }
77
+
78
+ // =============================================================================
79
+ // Error Report Types
80
+ // =============================================================================
81
+
82
+ /** Worker outcome types captured by the error collector */
83
+ export type ErrorOutcome =
84
+ | 'exception'
85
+ | 'exceededCpu'
86
+ | 'exceededMemory'
87
+ | 'canceled'
88
+ | 'responseStreamDisconnected'
89
+ | 'scriptNotFound'
90
+ | 'soft_error'
91
+ | 'warning';
92
+
93
+ /** Priority levels for error reports */
94
+ export type ErrorPriority = 'P0' | 'P1' | 'P2' | 'P3' | 'P4';
95
+
96
+ /**
97
+ * Error report structure — captured by the error-collector tail worker
98
+ * and optionally escalated to GitHub issues.
99
+ */
100
+ export interface ErrorReport {
101
+ /** Name of the worker that produced the error */
102
+ script_name: string;
103
+ /** Unique error identifier for deduplication */
104
+ fingerprint: string;
105
+ /** Error message text */
106
+ message: string;
107
+ /** Full stack trace if available */
108
+ stack_trace?: string;
109
+ /** Worker outcome type */
110
+ outcome?: ErrorOutcome;
111
+ /** Assigned priority level */
112
+ priority?: ErrorPriority;
113
+ /** Error category (e.g., unhandled-exception, quota-exhausted) */
114
+ category?: string;
115
+ /** Project the error belongs to */
116
+ project?: string;
117
+ /** When the error occurred (ISO 8601 UTC) */
118
+ timestamp?: string;
119
+ /** Unix timestamp in milliseconds from the tail event */
120
+ event_timestamp?: number;
121
+ }
122
+
123
+ // =============================================================================
124
+ // Circuit Breaker Types
125
+ // =============================================================================
126
+
127
+ /** Circuit breaker states stored in KV */
128
+ export type CircuitBreakerState = 'active' | 'warning' | 'paused';
129
+
130
+ /**
131
+ * Circuit breaker KV entry — stored at cb:{project}:{feature} key.
132
+ */
133
+ export interface CircuitBreakerEntry {
134
+ state: CircuitBreakerState;
135
+ tripped_at?: string;
136
+ reason?: string;
137
+ d1_writes_24h?: number;
138
+ d1_limit?: number;
139
+ }
@@ -0,0 +1,21 @@
1
+ import { defineConfig } from 'astro/config';
2
+ import cloudflare from '@astrojs/cloudflare';
3
+ import tailwind from '@astrojs/tailwind';
4
+ import react from '@astrojs/react';
5
+
6
+ export default defineConfig({
7
+ output: 'server',
8
+ adapter: cloudflare({
9
+ mode: 'directory',
10
+ imageService: 'passthrough',
11
+ }),
12
+ integrations: [tailwind(), react()],
13
+ vite: {
14
+ optimizeDeps: {
15
+ include: ['react', 'react-dom', 'react-dom/client'],
16
+ },
17
+ resolve: {
18
+ conditions: ['workerd', 'browser', 'import', 'module', 'default'],
19
+ },
20
+ },
21
+ });
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "{{projectSlug}}-dashboard",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "astro dev",
8
+ "build": "astro build",
9
+ "preview": "astro preview",
10
+ "check": "astro check"
11
+ },
12
+ "dependencies": {
13
+ "astro": "^5.0.0",
14
+ "@astrojs/cloudflare": "^12.0.0",
15
+ "@astrojs/react": "^4.0.0",
16
+ "@astrojs/tailwind": "^6.0.0",
17
+ "clsx": "^2.1.0",
18
+ "jose": "^5.2.0",
19
+ "lucide-react": "^0.300.0",
20
+ "react": "^19.0.0",
21
+ "react-dom": "^19.0.0",
22
+ "tailwindcss": "^3.4.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/react": "^19.0.0",
26
+ "@types/react-dom": "^19.0.0",
27
+ "typescript": "^5.7.0"
28
+ }
29
+ }