@littlebearapps/platform-admin-sdk 1.0.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 (94) hide show
  1. package/README.md +112 -0
  2. package/dist/index.d.ts +16 -0
  3. package/dist/index.js +89 -0
  4. package/dist/prompts.d.ts +27 -0
  5. package/dist/prompts.js +80 -0
  6. package/dist/scaffold.d.ts +5 -0
  7. package/dist/scaffold.js +65 -0
  8. package/dist/templates.d.ts +16 -0
  9. package/dist/templates.js +131 -0
  10. package/package.json +46 -0
  11. package/templates/full/migrations/006_pattern_discovery.sql +199 -0
  12. package/templates/full/migrations/007_notifications_search.sql +127 -0
  13. package/templates/full/workers/lib/pattern-discovery/ai-prompt.ts +644 -0
  14. package/templates/full/workers/lib/pattern-discovery/clustering.ts +278 -0
  15. package/templates/full/workers/lib/pattern-discovery/shadow-evaluation.ts +603 -0
  16. package/templates/full/workers/lib/pattern-discovery/storage.ts +806 -0
  17. package/templates/full/workers/lib/pattern-discovery/types.ts +159 -0
  18. package/templates/full/workers/lib/pattern-discovery/validation.ts +278 -0
  19. package/templates/full/workers/pattern-discovery.ts +661 -0
  20. package/templates/full/workers/platform-alert-router.ts +1809 -0
  21. package/templates/full/workers/platform-notifications.ts +424 -0
  22. package/templates/full/workers/platform-search.ts +480 -0
  23. package/templates/full/workers/platform-settings.ts +436 -0
  24. package/templates/full/wrangler.alert-router.jsonc.hbs +34 -0
  25. package/templates/full/wrangler.notifications.jsonc.hbs +23 -0
  26. package/templates/full/wrangler.pattern-discovery.jsonc.hbs +33 -0
  27. package/templates/full/wrangler.search.jsonc.hbs +16 -0
  28. package/templates/full/wrangler.settings.jsonc.hbs +23 -0
  29. package/templates/shared/README.md.hbs +69 -0
  30. package/templates/shared/config/budgets.yaml.hbs +72 -0
  31. package/templates/shared/config/services.yaml.hbs +45 -0
  32. package/templates/shared/migrations/001_core_tables.sql +117 -0
  33. package/templates/shared/migrations/002_usage_warehouse.sql +830 -0
  34. package/templates/shared/migrations/003_feature_tracking.sql +250 -0
  35. package/templates/shared/migrations/004_settings_alerts.sql +452 -0
  36. package/templates/shared/migrations/seed.sql.hbs +4 -0
  37. package/templates/shared/package.json.hbs +21 -0
  38. package/templates/shared/scripts/sync-config.ts +242 -0
  39. package/templates/shared/tsconfig.json +12 -0
  40. package/templates/shared/workers/lib/analytics-engine.ts +357 -0
  41. package/templates/shared/workers/lib/billing.ts +293 -0
  42. package/templates/shared/workers/lib/circuit-breaker-middleware.ts +25 -0
  43. package/templates/shared/workers/lib/control.ts +292 -0
  44. package/templates/shared/workers/lib/economics.ts +368 -0
  45. package/templates/shared/workers/lib/metrics.ts +103 -0
  46. package/templates/shared/workers/lib/platform-settings.ts +407 -0
  47. package/templates/shared/workers/lib/shared/allowances.ts +333 -0
  48. package/templates/shared/workers/lib/shared/cloudflare.ts +1362 -0
  49. package/templates/shared/workers/lib/shared/types.ts +58 -0
  50. package/templates/shared/workers/lib/telemetry-sampling.ts +360 -0
  51. package/templates/shared/workers/lib/usage/collectors/example.ts +96 -0
  52. package/templates/shared/workers/lib/usage/collectors/index.ts +128 -0
  53. package/templates/shared/workers/lib/usage/handlers/audit.ts +306 -0
  54. package/templates/shared/workers/lib/usage/handlers/backfill.ts +845 -0
  55. package/templates/shared/workers/lib/usage/handlers/behavioral.ts +429 -0
  56. package/templates/shared/workers/lib/usage/handlers/data-queries.ts +507 -0
  57. package/templates/shared/workers/lib/usage/handlers/dlq-admin.ts +364 -0
  58. package/templates/shared/workers/lib/usage/handlers/health-trends.ts +222 -0
  59. package/templates/shared/workers/lib/usage/handlers/index.ts +35 -0
  60. package/templates/shared/workers/lib/usage/handlers/usage-admin.ts +421 -0
  61. package/templates/shared/workers/lib/usage/handlers/usage-features.ts +1262 -0
  62. package/templates/shared/workers/lib/usage/handlers/usage-metrics.ts +2420 -0
  63. package/templates/shared/workers/lib/usage/handlers/usage-settings.ts +610 -0
  64. package/templates/shared/workers/lib/usage/queue/budget-enforcement.ts +1032 -0
  65. package/templates/shared/workers/lib/usage/queue/cost-budget-enforcement.ts +128 -0
  66. package/templates/shared/workers/lib/usage/queue/cost-calculator.ts +77 -0
  67. package/templates/shared/workers/lib/usage/queue/dlq-handler.ts +161 -0
  68. package/templates/shared/workers/lib/usage/queue/index.ts +19 -0
  69. package/templates/shared/workers/lib/usage/queue/telemetry-processor.ts +790 -0
  70. package/templates/shared/workers/lib/usage/scheduled/anomaly-detection.ts +732 -0
  71. package/templates/shared/workers/lib/usage/scheduled/data-collection.ts +956 -0
  72. package/templates/shared/workers/lib/usage/scheduled/error-digest.ts +343 -0
  73. package/templates/shared/workers/lib/usage/scheduled/index.ts +18 -0
  74. package/templates/shared/workers/lib/usage/scheduled/rollups.ts +1561 -0
  75. package/templates/shared/workers/lib/usage/shared/constants.ts +362 -0
  76. package/templates/shared/workers/lib/usage/shared/index.ts +14 -0
  77. package/templates/shared/workers/lib/usage/shared/types.ts +1066 -0
  78. package/templates/shared/workers/lib/usage/shared/utils.ts +795 -0
  79. package/templates/shared/workers/platform-usage.ts +1915 -0
  80. package/templates/shared/wrangler.usage.jsonc.hbs +58 -0
  81. package/templates/standard/migrations/005_error_collection.sql +162 -0
  82. package/templates/standard/workers/error-collector.ts +2670 -0
  83. package/templates/standard/workers/lib/error-collector/capture.ts +213 -0
  84. package/templates/standard/workers/lib/error-collector/digest.ts +448 -0
  85. package/templates/standard/workers/lib/error-collector/email-health-alerts.ts +262 -0
  86. package/templates/standard/workers/lib/error-collector/fingerprint.ts +258 -0
  87. package/templates/standard/workers/lib/error-collector/gap-alerts.ts +293 -0
  88. package/templates/standard/workers/lib/error-collector/github.ts +329 -0
  89. package/templates/standard/workers/lib/error-collector/types.ts +262 -0
  90. package/templates/standard/workers/lib/sentinel/gap-detection.ts +734 -0
  91. package/templates/standard/workers/lib/shared/slack-alerts.ts +585 -0
  92. package/templates/standard/workers/platform-sentinel.ts +1744 -0
  93. package/templates/standard/wrangler.error-collector.jsonc.hbs +44 -0
  94. package/templates/standard/wrangler.sentinel.jsonc.hbs +45 -0
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Platform Usage Constants
3
+ *
4
+ * Shared constants extracted from platform-usage.ts.
5
+ * Includes KV keys, mappings, defaults, and configuration.
6
+ */
7
+
8
+ import type { FeatureMetrics } from '@littlebearapps/platform-consumer-sdk';
9
+ import { METRIC_FIELDS } from '@littlebearapps/platform-consumer-sdk';
10
+ import { DEFAULT_PLATFORM_SETTINGS } from '../../platform-settings';
11
+ import type { DailyLimits, PlatformPricing } from './types';
12
+ import type { SimpleAllowanceType } from '../../shared/allowances';
13
+
14
+ // =============================================================================
15
+ // KV KEYS
16
+ // =============================================================================
17
+
18
+ /**
19
+ * KV keys for circuit breaker and sampling state.
20
+ *
21
+ * TODO: Add project-specific circuit breaker keys for your projects, e.g.:
22
+ * MY_PROJECT_STATUS: 'PROJECT:MY-PROJECT:STATUS',
23
+ */
24
+ export const CB_KEYS = {
25
+ // Global stop flag
26
+ GLOBAL_STOP: 'GLOBAL_STOP_ALL',
27
+ // Usage worker (adaptive sampling)
28
+ USAGE_SAMPLING_MODE: 'platform-usage:sampling-mode',
29
+ // D1 write tracking
30
+ D1_WRITES_24H: 'platform-usage:d1-writes-24h',
31
+ D1_WRITES_TIMESTAMP: 'platform-usage:d1-writes-timestamp',
32
+ // DO GB-seconds tracking (per-project)
33
+ DO_GB_SECONDS_24H_PREFIX: 'platform-usage:do-gb-seconds-24h:',
34
+ // Pricing configuration
35
+ PRICING: 'platform-usage:pricing:v1',
36
+ // Delta calculation state (hourly snapshot correction)
37
+ PREV_HOUR_ACCOUNT_METRICS: 'platform-usage:prev-hour:account',
38
+ PREV_HOUR_LAST_COLLECTION: 'platform-usage:prev-hour:timestamp',
39
+ } as const;
40
+
41
+ /**
42
+ * Feature KV key patterns (matching workers/lib/feature-budget.ts).
43
+ */
44
+ export const FEATURE_KV_KEYS = {
45
+ BUDGETS: 'CONFIG:BUDGETS',
46
+ enabled: (key: string) => `FEATURE:${key}:enabled`,
47
+ disabledReason: (key: string) => `FEATURE:${key}:disabled_reason`,
48
+ disabledAt: (key: string) => `FEATURE:${key}:disabled_at`,
49
+ autoResetAt: (key: string) => `FEATURE:${key}:auto_reset_at`,
50
+ alertLastSent: (key: string) => `ALERT:${key}:last_sent`,
51
+ } as const;
52
+
53
+ /**
54
+ * Settings key for alert thresholds in KV
55
+ */
56
+ export const SETTINGS_KEY = 'alert-thresholds:config';
57
+
58
+ // =============================================================================
59
+ // METRIC MAPPINGS
60
+ // =============================================================================
61
+
62
+ /**
63
+ * Mapping from FeatureMetrics (camelCase) to DailyLimits (snake_case).
64
+ */
65
+ export const METRIC_TO_BUDGET_KEY: Record<keyof FeatureMetrics, keyof DailyLimits | null> = {
66
+ d1Writes: 'd1_writes',
67
+ d1Reads: 'd1_reads',
68
+ d1RowsRead: 'd1_rows_read',
69
+ d1RowsWritten: 'd1_rows_written',
70
+ kvReads: 'kv_reads',
71
+ kvWrites: 'kv_writes',
72
+ kvDeletes: 'kv_deletes',
73
+ kvLists: 'kv_lists',
74
+ aiRequests: 'ai_requests',
75
+ aiNeurons: 'ai_neurons',
76
+ aiModelBreakdown: null, // Not a numeric metric, stored separately in D1
77
+ vectorizeQueries: 'vectorize_queries',
78
+ vectorizeInserts: 'vectorize_inserts',
79
+ r2ClassA: 'r2_class_a',
80
+ r2ClassB: 'r2_class_b',
81
+ queueMessages: 'queue_messages',
82
+ doRequests: 'do_requests',
83
+ doGbSeconds: null, // No budget limit for GB-seconds
84
+ doAvgLatencyMs: null, // Latency stats are informational, not budgeted
85
+ doMaxLatencyMs: null,
86
+ doP99LatencyMs: null,
87
+ workflowInvocations: 'workflow_invocations',
88
+ requests: 'requests',
89
+ cpuMs: 'cpu_ms',
90
+ };
91
+
92
+ /**
93
+ * Metric field order in Analytics Engine.
94
+ * Alias to SDK METRIC_FIELDS for backward compatibility.
95
+ */
96
+ export const FEATURE_METRIC_FIELDS = METRIC_FIELDS;
97
+
98
+ /**
99
+ * ResourceType mapping from GraphQL metric types to registry types.
100
+ */
101
+ export const RESOURCE_TYPE_MAP: Record<string, string> = {
102
+ worker: 'worker',
103
+ d1: 'd1',
104
+ kv: 'kv',
105
+ r2: 'r2',
106
+ vectorize: 'vectorize',
107
+ aiGateway: 'ai_gateway',
108
+ pages: 'pages',
109
+ durableObject: 'durable_object',
110
+ queue: 'queue',
111
+ workflow: 'workflow',
112
+ };
113
+
114
+ // =============================================================================
115
+ // QUEUE/WORKFLOW MAPPINGS
116
+ // =============================================================================
117
+
118
+ /**
119
+ * Queue-to-project mapping sets.
120
+ *
121
+ * TODO: Populate these with your project's queue names.
122
+ * Each Set maps queue names to a project for cost attribution.
123
+ *
124
+ * Example:
125
+ * export const MY_PROJECT_QUEUES = new Set([
126
+ * 'my-project-queue',
127
+ * 'my-project-dlq',
128
+ * ]);
129
+ */
130
+
131
+ /**
132
+ * Workflow-to-project mapping sets.
133
+ *
134
+ * TODO: Populate these with your project's workflow names.
135
+ *
136
+ * Example:
137
+ * export const MY_PROJECT_WORKFLOWS = new Set([
138
+ * 'my-workflow',
139
+ * ]);
140
+ */
141
+
142
+ // =============================================================================
143
+ // PRICING DEFAULTS
144
+ // =============================================================================
145
+
146
+ /**
147
+ * Default pricing constants (synced from CF_PRICING in shared/cloudflare.ts).
148
+ * These serve as fallback if KV pricing is not configured.
149
+ */
150
+ export const DEFAULT_PRICING: PlatformPricing = {
151
+ version: '2026-01-hardcoded',
152
+ workers: {
153
+ baseCostMonthly: 5.0,
154
+ includedRequests: 10_000_000,
155
+ requestsPerMillion: 0.3,
156
+ cpuMsPerMillion: 0.02,
157
+ },
158
+ d1: {
159
+ rowsReadPerBillion: 0.001,
160
+ rowsWrittenPerMillion: 1.0,
161
+ storagePerGb: 0.75,
162
+ },
163
+ kv: {
164
+ readsPerMillion: 0.5,
165
+ writesPerMillion: 5.0,
166
+ deletesPerMillion: 5.0,
167
+ listsPerMillion: 5.0,
168
+ storagePerGb: 0.5,
169
+ },
170
+ r2: {
171
+ storagePerGbMonth: 0.015,
172
+ classAPerMillion: 4.5,
173
+ classBPerMillion: 0.36,
174
+ },
175
+ vectorize: {
176
+ storedDimensionsPerMillion: 0.01,
177
+ queriedDimensionsPerMillion: 0.01,
178
+ },
179
+ workersAI: {
180
+ neuronsPerThousand: 0.011,
181
+ },
182
+ durableObjects: {
183
+ requestsPerMillion: 0.15,
184
+ gbSecondsPerMillion: 12.5,
185
+ storagePerGbMonth: 0.2,
186
+ readsPerMillion: 0.2,
187
+ writesPerMillion: 1.0,
188
+ deletesPerMillion: 1.0,
189
+ },
190
+ queues: {
191
+ messagesPerMillion: 0.4,
192
+ operationsPerMillion: 0.4,
193
+ },
194
+ pages: {
195
+ buildCost: 0.15,
196
+ bandwidthPerGb: 0.02,
197
+ },
198
+ };
199
+
200
+ /**
201
+ * Default budget thresholds (fallback if not configured in D1)
202
+ */
203
+ export const DEFAULT_BUDGET_THRESHOLDS = {
204
+ softBudgetLimit: DEFAULT_PLATFORM_SETTINGS.budgetSoftLimit,
205
+ warningThreshold: DEFAULT_PLATFORM_SETTINGS.budgetWarningThreshold,
206
+ };
207
+
208
+ /**
209
+ * Cloudflare overage pricing per unit
210
+ */
211
+ export const CF_OVERAGE_PRICING: Record<string, number> = {
212
+ workers: 0.3, // $0.30 per million requests
213
+ d1_reads: 0.001, // $0.001 per billion rows read (negligible)
214
+ d1_writes: 1.0, // $1.00 per million rows written
215
+ kv_reads: 0.5, // $0.50 per million reads
216
+ kv_writes: 5.0, // $5.00 per million writes
217
+ r2_class_a: 4.5, // $4.50 per million Class A ops
218
+ r2_class_b: 0.36, // $0.36 per million Class B ops
219
+ vectorize: 0.01, // $0.01 per million dimensions
220
+ workers_ai: 0.011, // $0.011 per 1000 neurons
221
+ };
222
+
223
+ // =============================================================================
224
+ // PROJECT CONFIGURATION
225
+ // =============================================================================
226
+
227
+ /**
228
+ * Fallback project configurations (used when D1 registry has no primaryResource).
229
+ *
230
+ * TODO: Populate with your project configurations.
231
+ *
232
+ * Example:
233
+ * 'my-project': { name: 'My Project', primaryResource: 'd1', customLimit: 20_000_000 },
234
+ */
235
+ export const FALLBACK_PROJECT_CONFIGS: Record<
236
+ string,
237
+ { name: string; primaryResource: SimpleAllowanceType; customLimit?: number }
238
+ > = {
239
+ // Add your projects here:
240
+ // 'my-project': { name: 'My Project', primaryResource: 'd1', customLimit: 20_000_000 },
241
+ };
242
+
243
+ // =============================================================================
244
+ // ERROR HANDLING
245
+ // =============================================================================
246
+
247
+ /**
248
+ * Error rate thresholds for alerting
249
+ */
250
+ export const ERROR_RATE_THRESHOLDS = {
251
+ P1: 10, // 10+ errors/hour = P1 critical
252
+ P2: 5, // 5+ errors/hour = P2 warning
253
+ WINDOW_HOURS: 1, // 1 hour window
254
+ COOLDOWN_MINUTES: 30, // 30 minute cooldown between alerts
255
+ // Extended thresholds for error rate monitoring
256
+ windowMinutes: 60, // 60 minute window for rate calculation
257
+ minRequests: 100, // Minimum requests before alerting
258
+ p0: 50, // 50% error rate = P0 immediate
259
+ };
260
+
261
+ // =============================================================================
262
+ // ANALYTICS ENGINE DATASETS
263
+ // =============================================================================
264
+
265
+ /**
266
+ * Known Analytics Engine datasets with metadata.
267
+ *
268
+ * TODO: Update with your project's Analytics Engine datasets.
269
+ */
270
+ export const KNOWN_DATASETS = [
271
+ // Platform SDK telemetry (all projects)
272
+ { name: 'platform-analytics', category: 'sdk', billable: true },
273
+ // TODO: Add your project-specific datasets here:
274
+ // { name: 'my-project-analytics', category: 'my-project', billable: true },
275
+ ];
276
+
277
+ /**
278
+ * Datasets that are actively queried (billable).
279
+ *
280
+ * TODO: Update with your actively-queried datasets.
281
+ */
282
+ export const QUERIED_DATASETS = new Set([
283
+ 'platform-analytics',
284
+ // TODO: Add your project-specific datasets here
285
+ ]);
286
+
287
+ // =============================================================================
288
+ // EXPECTED USAGE SETTINGS
289
+ // =============================================================================
290
+
291
+ /**
292
+ * Expected settings keys in D1 usage_settings table
293
+ */
294
+ export const EXPECTED_USAGE_SETTINGS = [
295
+ // Budget and alerting
296
+ 'budget_soft_limit',
297
+ 'budget_warning_threshold',
298
+ // D1 limits
299
+ 'd1_write_limit',
300
+ 'd1_write_warning_threshold',
301
+ 'd1_write_critical_threshold',
302
+ // Error rate thresholds
303
+ 'error_rate_p1_threshold',
304
+ 'error_rate_p2_threshold',
305
+ 'error_rate_window_hours',
306
+ 'error_rate_cooldown_minutes',
307
+ // Anomaly detection
308
+ 'anomaly_stddev_threshold',
309
+ 'anomaly_min_data_points',
310
+ // Circuit breaker
311
+ 'circuit_breaker_auto_reset_hours',
312
+ // Alert channel settings
313
+ 'slack_channel_alerts',
314
+ 'slack_channel_digests',
315
+ ];
316
+
317
+ // =============================================================================
318
+ // MAX HOURLY DELTAS (prevents cumulative inflation from delta calculation failures)
319
+ // =============================================================================
320
+
321
+ /**
322
+ * Maximum reasonable hourly delta values.
323
+ * Set to ~3x the monthly allowance prorated to 1 hour (div 730).
324
+ * Used to cap delta values when previous reference is missing (KV expired).
325
+ *
326
+ * Without these caps, a single hourly snapshot can store the entire billing-period
327
+ * cumulative total as a "delta", inflating SUM() totals by 10-100x.
328
+ */
329
+ export const MAX_HOURLY_DELTAS = {
330
+ vectorize_queries: 250_000, // 3x (50M / 730h) ~ 205K, with headroom
331
+ d1_rows_written: 2_000_000, // 3x (50M / 730h) ~ 205K, with headroom
332
+ d1_rows_read: 1_000_000_000, // 3x (25B / 730h) ~ 103M, with headroom
333
+ kv_reads: 500_000, // 3x (10M / 730h) ~ 41K, with headroom
334
+ kv_writes: 50_000, // 3x (1M / 730h) ~ 4.1K, with headroom
335
+ kv_deletes: 50_000,
336
+ kv_lists: 50_000,
337
+ workers_requests: 500_000, // 3x (10M / 730h) ~ 41K, with headroom
338
+ workers_errors: 100_000,
339
+ workers_cpu_ms: 50_000_000, // 50M ms/hr cap
340
+ do_requests: 10_000, // 3x (1M / 730h) ~ 4.1K, with headroom
341
+ do_gb_seconds: 5_000, // 3x (400K / 730h) ~ 1.6K, with headroom
342
+ r2_class_a: 50_000, // 3x (1M / 730h) ~ 4.1K, with headroom
343
+ r2_class_b: 500_000, // 3x (10M / 730h) ~ 41K, with headroom
344
+ r2_egress_bytes: 500_000_000, // 500MB/hr cap
345
+ ai_neurons: 10_000_000, // 10M neurons/hr cap
346
+ ai_requests: 100_000,
347
+ queue_produced: 50_000,
348
+ queue_consumed: 50_000,
349
+ workflow_executions: 10_000,
350
+ pages_deployments: 100,
351
+ ai_gateway_requests: 100_000,
352
+ ai_gateway_tokens: 50_000_000,
353
+ } as const;
354
+
355
+ // =============================================================================
356
+ // CACHE TTL
357
+ // =============================================================================
358
+
359
+ /**
360
+ * Billing settings cache TTL in milliseconds
361
+ */
362
+ export const BILLING_SETTINGS_CACHE_TTL_MS = 60_000; // 60 seconds
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared Usage Module Exports
3
+ *
4
+ * Barrel export for shared types, constants, and utilities.
5
+ */
6
+
7
+ // Types
8
+ export * from './types';
9
+
10
+ // Constants
11
+ export * from './constants';
12
+
13
+ // Utilities
14
+ export * from './utils';