@littlebearapps/platform-admin-sdk 1.1.1 → 1.4.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 +201 -47
- package/dist/scaffold.js +3 -0
- package/dist/templates.d.ts +1 -1
- package/dist/templates.js +4 -1
- package/package.json +13 -3
- package/templates/full/workers/lib/pattern-discovery/index.ts +13 -0
- package/templates/full/workers/lib/pattern-discovery/storage.ts +1 -0
- package/templates/shared/config/services.yaml.hbs +99 -0
- package/templates/shared/docs/kv-key-patterns.md +101 -0
- package/templates/shared/migrations/002_usage_warehouse.sql +1 -0
- package/templates/shared/migrations/seed.sql.hbs +2 -2
- package/templates/shared/scripts/sync-config.ts +59 -5
- package/templates/shared/workers/lib/platform-settings.ts +16 -1
- package/templates/shared/workers/lib/usage/queue/budget-enforcement.ts +11 -5
- package/templates/shared/workers/lib/usage/scheduled/anomaly-detection.ts +23 -8
- package/templates/shared/workers/lib/usage/scheduled/rollups.ts +8 -5
- package/templates/shared/wrangler.usage.jsonc.hbs +1 -1
- package/templates/standard/workers/error-collector.ts +179 -362
- package/templates/standard/workers/lib/sentinel/gap-detection.ts +48 -8
- package/templates/standard/workers/platform-sentinel.ts +4 -4
- package/templates/standard/wrangler.sentinel.jsonc.hbs +1 -3
package/README.md
CHANGED
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
Generates workers, D1 migrations, and config files. Run once, then you own the code.
|
|
6
6
|
|
|
7
|
+
> **Using Claude Code?** Install the [Platform SDK Plugin](https://github.com/littlebearapps/platform-sdk-plugin) for automated SDK convention enforcement — it validates wrangler bindings, budget wrappers, and cost safety patterns in real time.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
- **Node.js 20+** and npm
|
|
12
|
+
- **wrangler CLI** installed and authenticated (`npx wrangler whoami`)
|
|
13
|
+
- **Cloudflare Workers Paid plan** (required for KV, Queues, and D1)
|
|
14
|
+
- **GitHub organisation** (Standard/Full tiers — for error collection GitHub issues)
|
|
15
|
+
- **Gatus instance** (optional — for heartbeat monitoring)
|
|
16
|
+
|
|
7
17
|
## Usage
|
|
8
18
|
|
|
9
19
|
```bash
|
|
@@ -17,9 +27,12 @@ The CLI prompts for:
|
|
|
17
27
|
- **Gatus URL** (optional) — for heartbeat monitoring
|
|
18
28
|
- **Default assignee** — GitHub username for error issues
|
|
19
29
|
|
|
20
|
-
### CLI
|
|
30
|
+
### CLI Commands
|
|
31
|
+
|
|
32
|
+
#### `scaffold` (default)
|
|
21
33
|
|
|
22
34
|
```bash
|
|
35
|
+
npx @littlebearapps/platform-admin-sdk my-platform
|
|
23
36
|
npx @littlebearapps/platform-admin-sdk my-platform --tier full --github-org myorg --skip-prompts
|
|
24
37
|
```
|
|
25
38
|
|
|
@@ -31,6 +44,27 @@ npx @littlebearapps/platform-admin-sdk my-platform --tier full --github-org myor
|
|
|
31
44
|
| `--default-assignee <user>` | Default GitHub issue assignee |
|
|
32
45
|
| `--skip-prompts` | Fail if required flags missing (for CI/automation) |
|
|
33
46
|
|
|
47
|
+
#### `upgrade`
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx @littlebearapps/platform-admin-sdk upgrade
|
|
51
|
+
npx @littlebearapps/platform-admin-sdk upgrade --dry-run
|
|
52
|
+
npx @littlebearapps/platform-admin-sdk upgrade --tier standard
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Flag | Description |
|
|
56
|
+
|------|------------|
|
|
57
|
+
| `--dry-run` | Preview changes without writing files |
|
|
58
|
+
| `--tier <tier>` | Upgrade to a higher tier |
|
|
59
|
+
|
|
60
|
+
#### `adopt`
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx @littlebearapps/platform-admin-sdk adopt . --tier minimal --project-name my-platform --skip-prompts
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Creates a `.platform-scaffold.json` manifest for projects scaffolded before v1.1.0. See [Upgrade vs Adopt](#upgrade-vs-adopt).
|
|
67
|
+
|
|
34
68
|
## Tiers
|
|
35
69
|
|
|
36
70
|
| Tier | Workers | What You Get | Est. Cost |
|
|
@@ -39,69 +73,159 @@ npx @littlebearapps/platform-admin-sdk my-platform --tier full --github-org myor
|
|
|
39
73
|
| **Standard** | 3 | + Error collector (auto GitHub issues), gap detection sentinel | ~$0/mo |
|
|
40
74
|
| **Full** | 8 | + AI pattern discovery, alert router, notifications, search, settings | ~$5/mo |
|
|
41
75
|
|
|
76
|
+
See [Tier Comparison](../../docs/admin-sdk/tiers.md) for a detailed breakdown of what each tier generates.
|
|
77
|
+
|
|
42
78
|
## What Gets Generated
|
|
43
79
|
|
|
44
80
|
### All tiers
|
|
45
81
|
|
|
46
82
|
```
|
|
47
83
|
my-platform/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
84
|
+
├── platform/config/
|
|
85
|
+
│ ├── services.yaml # Project registry, feature definitions
|
|
86
|
+
│ └── budgets.yaml # Daily limits, circuit breaker thresholds
|
|
87
|
+
├── storage/d1/migrations/ # D1 schema (4 core migrations + seed)
|
|
88
|
+
├── workers/
|
|
89
|
+
│ ├── platform-usage.ts # Data warehouse worker (cron + queue consumer)
|
|
90
|
+
│ └── lib/ # Shared libraries (billing, analytics, budgets)
|
|
91
|
+
├── docs/
|
|
92
|
+
│ └── kv-key-patterns.md # KV key prefix reference
|
|
93
|
+
├── scripts/
|
|
94
|
+
│ └── sync-config.ts # Sync YAML config to D1/KV
|
|
95
|
+
├── wrangler.*.jsonc # Worker configs with binding placeholders
|
|
96
|
+
├── package.json
|
|
97
|
+
├── tsconfig.json
|
|
98
|
+
└── README.md
|
|
61
99
|
```
|
|
62
100
|
|
|
101
|
+
### Key generated files
|
|
102
|
+
|
|
103
|
+
| File | Purpose |
|
|
104
|
+
|------|---------|
|
|
105
|
+
| `platform/config/services.yaml` | Project registry — feature definitions, connections, metadata |
|
|
106
|
+
| `platform/config/budgets.yaml` | Daily limits, circuit breaker thresholds, warning percentages |
|
|
107
|
+
| `storage/d1/migrations/001_*.sql` | Core tables: project registry, resource snapshots, daily rollups |
|
|
108
|
+
| `workers/platform-usage.ts` | Central data warehouse — receives queue telemetry, stores in D1 |
|
|
109
|
+
| `scripts/sync-config.ts` | Syncs YAML config to D1 + KV (run after config changes) |
|
|
110
|
+
|
|
63
111
|
### Standard tier adds
|
|
64
112
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
113
|
+
| File | Purpose |
|
|
114
|
+
|------|---------|
|
|
115
|
+
| `workers/error-collector.ts` | Tail worker — creates GitHub issues from worker errors |
|
|
116
|
+
| `workers/platform-sentinel.ts` | Gap detection, cost monitoring, alerts |
|
|
117
|
+
| `workers/lib/error-collector/` | Fingerprinting, deduplication, digest generation |
|
|
118
|
+
| `workers/lib/sentinel/` | Per-project gap detection |
|
|
119
|
+
| `storage/d1/migrations/005_error_collection.sql` | Error tables: occurrences, fingerprint decisions, digests |
|
|
70
120
|
|
|
71
121
|
### Full tier adds
|
|
72
122
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
123
|
+
| File | Purpose |
|
|
124
|
+
|------|---------|
|
|
125
|
+
| `workers/pattern-discovery.ts` | AI-assisted transient error pattern discovery |
|
|
126
|
+
| `workers/platform-alert-router.ts` | Unified alert normalisation and routing |
|
|
127
|
+
| `workers/platform-notifications.ts` | In-app notification API |
|
|
128
|
+
| `workers/platform-search.ts` | Full-text search (FTS5) |
|
|
129
|
+
| `workers/platform-settings.ts` | Settings management API |
|
|
130
|
+
| `workers/lib/pattern-discovery/` | Types, clustering, AI prompts, validation, shadow evaluation |
|
|
131
|
+
| `storage/d1/migrations/006_pattern_discovery.sql` | Pattern tables |
|
|
132
|
+
| `storage/d1/migrations/007_notifications_search.sql` | Notification and search tables |
|
|
81
133
|
|
|
82
134
|
## Post-Scaffold Steps
|
|
83
135
|
|
|
136
|
+
### 1. Install dependencies
|
|
137
|
+
|
|
84
138
|
```bash
|
|
85
139
|
cd my-platform
|
|
86
140
|
npm install
|
|
141
|
+
```
|
|
87
142
|
|
|
88
|
-
|
|
143
|
+
### 2. Create Cloudflare resources
|
|
144
|
+
|
|
145
|
+
**All tiers:**
|
|
146
|
+
|
|
147
|
+
```bash
|
|
89
148
|
npx wrangler d1 create my-platform-metrics
|
|
90
149
|
npx wrangler kv namespace create PLATFORM_CACHE
|
|
91
150
|
npx wrangler queues create my-platform-telemetry
|
|
92
151
|
npx wrangler queues create my-platform-telemetry-dlq
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Standard tier** — also create:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npx wrangler kv namespace create PLATFORM_ALERTS
|
|
158
|
+
```
|
|
93
159
|
|
|
94
|
-
|
|
160
|
+
**Full tier** — also create:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
npx wrangler kv namespace create SERVICE_REGISTRY
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Update the resource IDs in each `wrangler.*.jsonc` file.
|
|
167
|
+
|
|
168
|
+
### 3. Configure secrets
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Standard tier — error-collector (GitHub App for auto-issue creation)
|
|
172
|
+
npx wrangler secret put GITHUB_APP_ID -c wrangler.my-platform-error-collector.jsonc
|
|
173
|
+
npx wrangler secret put GITHUB_APP_PRIVATE_KEY -c wrangler.my-platform-error-collector.jsonc
|
|
174
|
+
npx wrangler secret put GITHUB_APP_INSTALLATION_ID -c wrangler.my-platform-error-collector.jsonc
|
|
175
|
+
|
|
176
|
+
# Standard tier — sentinel (Cloudflare API for cost monitoring)
|
|
177
|
+
npx wrangler secret put CLOUDFLARE_API_TOKEN -c wrangler.my-platform-sentinel.jsonc
|
|
178
|
+
|
|
179
|
+
# Optional — Slack alerts (any worker with SLACK_WEBHOOK_URL)
|
|
180
|
+
npx wrangler secret put SLACK_WEBHOOK_URL -c wrangler.my-platform-sentinel.jsonc
|
|
181
|
+
|
|
182
|
+
# Full tier — alert-router (GitHub token for issue creation)
|
|
183
|
+
npx wrangler secret put GITHUB_TOKEN -c wrangler.my-platform-alert-router.jsonc
|
|
184
|
+
npx wrangler secret put SLACK_WEBHOOK_URL -c wrangler.my-platform-alert-router.jsonc
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 4. Apply migrations and deploy
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Sync config to D1/KV
|
|
95
191
|
npm run sync:config
|
|
192
|
+
|
|
193
|
+
# Apply D1 migrations
|
|
96
194
|
npx wrangler d1 migrations apply my-platform-metrics --remote
|
|
195
|
+
|
|
196
|
+
# Deploy workers (order matters — deploy usage first, then tail consumers)
|
|
97
197
|
npx wrangler deploy -c wrangler.my-platform-usage.jsonc
|
|
198
|
+
|
|
199
|
+
# Standard tier
|
|
200
|
+
npx wrangler deploy -c wrangler.my-platform-error-collector.jsonc
|
|
201
|
+
npx wrangler deploy -c wrangler.my-platform-sentinel.jsonc
|
|
202
|
+
|
|
203
|
+
# Full tier
|
|
204
|
+
npx wrangler deploy -c wrangler.my-platform-notifications.jsonc
|
|
205
|
+
npx wrangler deploy -c wrangler.my-platform-search.jsonc
|
|
206
|
+
npx wrangler deploy -c wrangler.my-platform-settings.jsonc
|
|
207
|
+
npx wrangler deploy -c wrangler.my-platform-pattern-discovery.jsonc
|
|
208
|
+
npx wrangler deploy -c wrangler.my-platform-alert-router.jsonc
|
|
98
209
|
```
|
|
99
210
|
|
|
100
|
-
|
|
211
|
+
See [Quickstart Guide](../../docs/admin-sdk/quickstart.md) for a detailed walkthrough.
|
|
212
|
+
|
|
213
|
+
## The Manifest File
|
|
214
|
+
|
|
215
|
+
When you scaffold or upgrade, the SDK writes a `.platform-scaffold.json` file. **Commit this to git** — it's how `upgrade` knows what to update.
|
|
101
216
|
|
|
102
|
-
|
|
217
|
+
The manifest contains:
|
|
218
|
+
- **`sdkVersion`** — Version of the Admin SDK that generated the files
|
|
219
|
+
- **`tier`** — Infrastructure tier (minimal/standard/full)
|
|
220
|
+
- **`context`** — Project name, slug, organisation, and other scaffold-time settings
|
|
221
|
+
- **`files`** — SHA-256 hash of each generated file as originally written
|
|
222
|
+
- **`highestScaffoldMigration`** — Highest D1 migration number generated
|
|
103
223
|
|
|
104
|
-
|
|
224
|
+
The `files` hash map is the basis for the three-way merge during `upgrade`: if your current disk content matches the original hash, the file is "unmodified" and can be safely updated. If the disk content differs, you've customised it and `upgrade` skips it with a warning.
|
|
225
|
+
|
|
226
|
+
## Updating Your Platform
|
|
227
|
+
|
|
228
|
+
### Upgrade (v1.1.0+)
|
|
105
229
|
|
|
106
230
|
```bash
|
|
107
231
|
cd my-platform
|
|
@@ -110,9 +234,9 @@ npx @littlebearapps/platform-admin-sdk upgrade
|
|
|
110
234
|
|
|
111
235
|
The upgrade command:
|
|
112
236
|
- **Creates** new files added in the SDK update
|
|
113
|
-
- **Updates** files you haven't modified (compares content hashes)
|
|
114
|
-
- **Skips** files you've customised (with a warning)
|
|
115
|
-
- **Renumbers** new migrations
|
|
237
|
+
- **Updates** files you haven't modified (compares content hashes from manifest)
|
|
238
|
+
- **Skips** files you've customised (with a warning showing which files were skipped)
|
|
239
|
+
- **Renumbers** new D1 migrations above your highest existing migration
|
|
116
240
|
|
|
117
241
|
Preview changes without writing:
|
|
118
242
|
|
|
@@ -126,15 +250,22 @@ Upgrade to a higher tier:
|
|
|
126
250
|
npx @littlebearapps/platform-admin-sdk upgrade --tier standard
|
|
127
251
|
```
|
|
128
252
|
|
|
129
|
-
###
|
|
130
|
-
|
|
131
|
-
Projects scaffolded before v1.1.0 don't have a manifest. Run `adopt` first:
|
|
253
|
+
### Upgrade vs Adopt
|
|
132
254
|
|
|
133
|
-
```bash
|
|
134
|
-
npx @littlebearapps/platform-admin-sdk adopt . --tier minimal --project-name my-platform --skip-prompts
|
|
135
255
|
```
|
|
256
|
+
Do you have .platform-scaffold.json in your project?
|
|
257
|
+
│
|
|
258
|
+
├── YES → Run: npx @littlebearapps/platform-admin-sdk upgrade
|
|
259
|
+
│ (three-way merge using manifest hashes)
|
|
260
|
+
│
|
|
261
|
+
└── NO → Run: npx @littlebearapps/platform-admin-sdk adopt . --tier <your-tier>
|
|
262
|
+
(creates manifest by hashing existing files as baseline)
|
|
263
|
+
Then run: npx @littlebearapps/platform-admin-sdk upgrade
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Projects scaffolded before v1.1.0 don't have a manifest. The `adopt` command hashes your existing SDK-generated files as the "original" state, creating a baseline for future upgrades.
|
|
136
267
|
|
|
137
|
-
|
|
268
|
+
See [Upgrade Guide](../../docs/admin-sdk/upgrade-guide.md) for detailed instructions.
|
|
138
269
|
|
|
139
270
|
## Data Safety
|
|
140
271
|
|
|
@@ -151,20 +282,43 @@ The scaffolder generates core infrastructure only. It does **not** create:
|
|
|
151
282
|
- Email workers or notification templates
|
|
152
283
|
- Data connectors (Stripe, GA4, Plausible, etc.)
|
|
153
284
|
- Test suites
|
|
154
|
-
- CI/CD workflows
|
|
285
|
+
- CI/CD workflows (use the [consumer-check.yml](../../docs/admin-sdk/ci-workflow.md) reusable workflow)
|
|
155
286
|
|
|
156
287
|
These are project-specific — build them as you need them.
|
|
157
288
|
|
|
158
|
-
## Consumer SDK
|
|
289
|
+
## Consumer SDK Integration
|
|
159
290
|
|
|
160
|
-
The generated workers use `@littlebearapps/platform-consumer-sdk`
|
|
291
|
+
The generated backend workers use `@littlebearapps/platform-consumer-sdk` internally. To connect your application workers, install the Consumer SDK and add the required bindings:
|
|
161
292
|
|
|
162
293
|
```bash
|
|
163
294
|
npm install @littlebearapps/platform-consumer-sdk
|
|
164
295
|
```
|
|
165
296
|
|
|
166
|
-
|
|
297
|
+
Add to each application worker's `wrangler.jsonc`:
|
|
298
|
+
|
|
299
|
+
```jsonc
|
|
300
|
+
{
|
|
301
|
+
"kv_namespaces": [
|
|
302
|
+
{ "binding": "PLATFORM_CACHE", "id": "YOUR_KV_NAMESPACE_ID" }
|
|
303
|
+
],
|
|
304
|
+
"queues": {
|
|
305
|
+
"producers": [
|
|
306
|
+
{ "binding": "TELEMETRY_QUEUE", "queue": "my-platform-telemetry" }
|
|
307
|
+
]
|
|
308
|
+
},
|
|
309
|
+
// Standard/Full tier — route errors to error-collector
|
|
310
|
+
"tail_consumers": [
|
|
311
|
+
{ "service": "my-platform-error-collector" }
|
|
312
|
+
]
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
See the [Consumer SDK README](../consumer-sdk/README.md) for integration details and the [First Worker tutorial](../../docs/guides/first-worker.md) for a complete walkthrough.
|
|
317
|
+
|
|
318
|
+
## Multi-Account Support
|
|
319
|
+
|
|
320
|
+
The Admin SDK's programmatic API accepts `accountId` and `apiToken` per call, enabling cross-account monitoring and emergency control from a single script or worker. See the [Multi-Account Setup guide](../../docs/guides/multi-account.md) for architecture patterns.
|
|
167
321
|
|
|
168
|
-
##
|
|
322
|
+
## Licence
|
|
169
323
|
|
|
170
|
-
MIT
|
|
324
|
+
MIT — Made with ❤️ by [Little Bear Apps](https://littlebearapps.com) 🐶
|
package/dist/scaffold.js
CHANGED
|
@@ -45,6 +45,9 @@ export async function scaffold(options, outputDir) {
|
|
|
45
45
|
gatusUrl: options.gatusUrl,
|
|
46
46
|
defaultAssignee: options.defaultAssignee,
|
|
47
47
|
sdkVersion: SDK_VERSION,
|
|
48
|
+
// Computed flags for Handlebars conditionals in templates
|
|
49
|
+
isStandard: (options.tier === 'standard' || options.tier === 'full') ? 'true' : '',
|
|
50
|
+
isFull: options.tier === 'full' ? 'true' : '',
|
|
48
51
|
};
|
|
49
52
|
mkdirSync(outputDir, { recursive: true });
|
|
50
53
|
const fileHashes = {};
|
package/dist/templates.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { Tier } from './prompts.js';
|
|
8
8
|
/** Single source of truth for the SDK version. */
|
|
9
|
-
export declare const SDK_VERSION = "1.
|
|
9
|
+
export declare const SDK_VERSION = "1.4.0";
|
|
10
10
|
/** Returns true if `to` is the same or higher tier than `from`. */
|
|
11
11
|
export declare function isTierUpgradeOrSame(from: Tier, to: Tier): boolean;
|
|
12
12
|
/** Check if a template file is a numbered migration (not seed.sql). */
|
package/dist/templates.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* All other files are copied verbatim.
|
|
6
6
|
*/
|
|
7
7
|
/** Single source of truth for the SDK version. */
|
|
8
|
-
export const SDK_VERSION = '1.
|
|
8
|
+
export const SDK_VERSION = '1.4.0';
|
|
9
9
|
/** Tier ordering for upgrade validation. */
|
|
10
10
|
const TIER_ORDER = { minimal: 0, standard: 1, full: 2 };
|
|
11
11
|
/** Returns true if `to` is the same or higher tier than `from`. */
|
|
@@ -82,6 +82,8 @@ const SHARED_FILES = [
|
|
|
82
82
|
// Workers — lib/usage/collectors (pluggable interface + example)
|
|
83
83
|
{ src: 'shared/workers/lib/usage/collectors/index.ts', dest: 'workers/lib/usage/collectors/index.ts', template: false },
|
|
84
84
|
{ src: 'shared/workers/lib/usage/collectors/example.ts', dest: 'workers/lib/usage/collectors/example.ts', template: false },
|
|
85
|
+
// Documentation
|
|
86
|
+
{ src: 'shared/docs/kv-key-patterns.md', dest: 'docs/kv-key-patterns.md', template: false },
|
|
85
87
|
];
|
|
86
88
|
const STANDARD_FILES = [
|
|
87
89
|
// Additional migrations
|
|
@@ -116,6 +118,7 @@ const FULL_FILES = [
|
|
|
116
118
|
{ src: 'full/wrangler.settings.jsonc.hbs', dest: 'wrangler.{{projectSlug}}-settings.jsonc', template: true },
|
|
117
119
|
// Workers — pattern-discovery (AI-assisted transient error patterns)
|
|
118
120
|
{ src: 'full/workers/pattern-discovery.ts', dest: 'workers/pattern-discovery.ts', template: false },
|
|
121
|
+
{ src: 'full/workers/lib/pattern-discovery/index.ts', dest: 'workers/lib/pattern-discovery/index.ts', template: false },
|
|
119
122
|
{ src: 'full/workers/lib/pattern-discovery/types.ts', dest: 'workers/lib/pattern-discovery/types.ts', template: false },
|
|
120
123
|
{ src: 'full/workers/lib/pattern-discovery/clustering.ts', dest: 'workers/lib/pattern-discovery/clustering.ts', template: false },
|
|
121
124
|
{ src: 'full/workers/lib/pattern-discovery/ai-prompt.ts', dest: 'workers/lib/pattern-discovery/ai-prompt.ts', template: false },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@littlebearapps/platform-admin-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Platform Admin SDK — scaffold backend infrastructure with workers, circuit breakers, and cost protection for Cloudflare",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -35,12 +35,22 @@
|
|
|
35
35
|
"directory": "packages/admin-sdk"
|
|
36
36
|
},
|
|
37
37
|
"keywords": [
|
|
38
|
+
"cloudflare",
|
|
38
39
|
"cloudflare-workers",
|
|
39
|
-
"platform-admin-sdk",
|
|
40
40
|
"scaffold",
|
|
41
41
|
"cost-protection",
|
|
42
|
-
"circuit-breaker"
|
|
42
|
+
"circuit-breaker",
|
|
43
|
+
"billing-safety",
|
|
44
|
+
"observability",
|
|
45
|
+
"telemetry",
|
|
46
|
+
"budget-enforcement",
|
|
47
|
+
"error-collection",
|
|
48
|
+
"usage-monitoring"
|
|
43
49
|
],
|
|
50
|
+
"homepage": "https://github.com/littlebearapps/platform-sdks#readme",
|
|
51
|
+
"bugs": {
|
|
52
|
+
"url": "https://github.com/littlebearapps/platform-sdks/issues"
|
|
53
|
+
},
|
|
44
54
|
"author": "Little Bear Apps",
|
|
45
55
|
"license": "MIT"
|
|
46
56
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Discovery Module
|
|
3
|
+
*
|
|
4
|
+
* AI-assisted discovery of transient error patterns.
|
|
5
|
+
*
|
|
6
|
+
* @module workers/lib/pattern-discovery
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export * from './types';
|
|
10
|
+
export * from './clustering';
|
|
11
|
+
export * from './ai-prompt';
|
|
12
|
+
export * from './validation';
|
|
13
|
+
export * from './storage';
|
|
@@ -20,6 +20,50 @@ projects:
|
|
|
20
20
|
script_name: {{projectSlug}}-usage
|
|
21
21
|
status: active
|
|
22
22
|
schedule: "0 * * * *"
|
|
23
|
+
{{#if isStandard}}
|
|
24
|
+
|
|
25
|
+
- id: {{projectSlug}}-error-collector
|
|
26
|
+
name: "Error Collector"
|
|
27
|
+
script_name: {{projectSlug}}-error-collector
|
|
28
|
+
status: active
|
|
29
|
+
schedule: "*/15 * * * *"
|
|
30
|
+
metadata:
|
|
31
|
+
type: tail-worker
|
|
32
|
+
|
|
33
|
+
- id: {{projectSlug}}-sentinel
|
|
34
|
+
name: "Platform Sentinel"
|
|
35
|
+
script_name: {{projectSlug}}-sentinel
|
|
36
|
+
status: active
|
|
37
|
+
schedule: "*/15 * * * *"
|
|
38
|
+
{{/if}}
|
|
39
|
+
{{#if isFull}}
|
|
40
|
+
|
|
41
|
+
- id: {{projectSlug}}-pattern-discovery
|
|
42
|
+
name: "Pattern Discovery"
|
|
43
|
+
script_name: {{projectSlug}}-pattern-discovery
|
|
44
|
+
status: active
|
|
45
|
+
schedule: "0 2 * * *"
|
|
46
|
+
|
|
47
|
+
- id: {{projectSlug}}-alert-router
|
|
48
|
+
name: "Alert Router"
|
|
49
|
+
script_name: {{projectSlug}}-alert-router
|
|
50
|
+
status: active
|
|
51
|
+
|
|
52
|
+
- id: {{projectSlug}}-notifications
|
|
53
|
+
name: "Notifications"
|
|
54
|
+
script_name: {{projectSlug}}-notifications
|
|
55
|
+
status: active
|
|
56
|
+
|
|
57
|
+
- id: {{projectSlug}}-search
|
|
58
|
+
name: "Search"
|
|
59
|
+
script_name: {{projectSlug}}-search
|
|
60
|
+
status: active
|
|
61
|
+
|
|
62
|
+
- id: {{projectSlug}}-settings
|
|
63
|
+
name: "Settings"
|
|
64
|
+
script_name: {{projectSlug}}-settings
|
|
65
|
+
status: active
|
|
66
|
+
{{/if}}
|
|
23
67
|
storage:
|
|
24
68
|
d1:
|
|
25
69
|
- database_name: {{projectSlug}}-metrics
|
|
@@ -43,3 +87,58 @@ projects:
|
|
|
43
87
|
feature_id: "{{projectSlug}}:queue:telemetry"
|
|
44
88
|
circuit_breaker: true
|
|
45
89
|
cost_tier: low
|
|
90
|
+
{{#if isStandard}}
|
|
91
|
+
error-collection:
|
|
92
|
+
tail-processing:
|
|
93
|
+
display_name: "Error Tail Processing"
|
|
94
|
+
feature_id: "{{projectSlug}}:error-collection:tail"
|
|
95
|
+
circuit_breaker: true
|
|
96
|
+
cost_tier: medium
|
|
97
|
+
daily-digest:
|
|
98
|
+
display_name: "Error Daily Digest"
|
|
99
|
+
feature_id: "{{projectSlug}}:error-collection:digest"
|
|
100
|
+
circuit_breaker: true
|
|
101
|
+
cost_tier: low
|
|
102
|
+
gap-alerts:
|
|
103
|
+
display_name: "Gap Alert Processing"
|
|
104
|
+
feature_id: "{{projectSlug}}:error-collection:gap-alerts"
|
|
105
|
+
circuit_breaker: false
|
|
106
|
+
cost_tier: low
|
|
107
|
+
monitor:
|
|
108
|
+
sentinel:
|
|
109
|
+
display_name: "Platform Sentinel"
|
|
110
|
+
feature_id: "{{projectSlug}}:monitor:sentinel"
|
|
111
|
+
circuit_breaker: true
|
|
112
|
+
cost_tier: low
|
|
113
|
+
{{/if}}
|
|
114
|
+
{{#if isFull}}
|
|
115
|
+
pattern-discovery:
|
|
116
|
+
ai-discovery:
|
|
117
|
+
display_name: "AI Pattern Discovery"
|
|
118
|
+
feature_id: "{{projectSlug}}:pattern-discovery:ai"
|
|
119
|
+
circuit_breaker: true
|
|
120
|
+
cost_tier: high
|
|
121
|
+
shadow-evaluation:
|
|
122
|
+
display_name: "Shadow Evaluation"
|
|
123
|
+
feature_id: "{{projectSlug}}:pattern-discovery:shadow"
|
|
124
|
+
circuit_breaker: true
|
|
125
|
+
cost_tier: medium
|
|
126
|
+
notifications:
|
|
127
|
+
api:
|
|
128
|
+
display_name: "Notifications API"
|
|
129
|
+
feature_id: "{{projectSlug}}:notifications:api"
|
|
130
|
+
circuit_breaker: true
|
|
131
|
+
cost_tier: low
|
|
132
|
+
search:
|
|
133
|
+
api:
|
|
134
|
+
display_name: "Search API"
|
|
135
|
+
feature_id: "{{projectSlug}}:search:api"
|
|
136
|
+
circuit_breaker: true
|
|
137
|
+
cost_tier: low
|
|
138
|
+
settings:
|
|
139
|
+
api:
|
|
140
|
+
display_name: "Settings API"
|
|
141
|
+
feature_id: "{{projectSlug}}:settings:api"
|
|
142
|
+
circuit_breaker: true
|
|
143
|
+
cost_tier: low
|
|
144
|
+
{{/if}}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# KV Key Patterns Reference
|
|
2
|
+
|
|
3
|
+
All keys stored in the `PLATFORM_CACHE` KV namespace, grouped by subsystem.
|
|
4
|
+
|
|
5
|
+
> Generated by `@littlebearapps/platform-admin-sdk`. Keep this up to date as you add features.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Circuit Breaker State
|
|
10
|
+
|
|
11
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
12
|
+
|---|---|---|---|---|
|
|
13
|
+
| `GLOBAL_STOP_ALL` | `GLOBAL_STOP_ALL` | None | platform-usage | Emergency kill switch — pauses all operations |
|
|
14
|
+
| `PROJECT:{slug}:STATUS` | `PROJECT:MY-APP:STATUS` | None | platform-usage | Per-project circuit breaker state (`active`/`warning`/`paused`) |
|
|
15
|
+
| `FEATURE:{key}:enabled` | `FEATURE:my-app:scanner:enabled` | None | platform-usage | Feature-level on/off flag |
|
|
16
|
+
| `FEATURE:{key}:disabled_reason` | `FEATURE:my-app:scanner:disabled_reason` | None | platform-usage | Why feature was disabled |
|
|
17
|
+
| `FEATURE:{key}:disabled_at` | `FEATURE:my-app:scanner:disabled_at` | None | platform-usage | Timestamp of disable |
|
|
18
|
+
| `FEATURE:{key}:auto_reset_at` | `FEATURE:my-app:scanner:auto_reset_at` | None | platform-usage | Auto-reset timestamp |
|
|
19
|
+
|
|
20
|
+
## Budget Enforcement
|
|
21
|
+
|
|
22
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
23
|
+
|---|---|---|---|---|
|
|
24
|
+
| `CONFIG:BUDGETS` | `CONFIG:BUDGETS` | None (synced) | sync-config | Budget JSON from budgets.yaml |
|
|
25
|
+
| `CONFIG:FEATURE:{key}:BUDGET_MONTHLY` | `CONFIG:FEATURE:my-app:scanner:BUDGET_MONTHLY` | None | sync-config | Monthly budget limit for feature |
|
|
26
|
+
| `BUDGET_WARN:{feature}:{metric}:{threshold}` | `BUDGET_WARN:my-app:scanner:d1_writes:70` | 1hr | platform-usage | Budget warning dedup (prevents duplicate Slack alerts) |
|
|
27
|
+
| `BUDGET_WARN_MONTHLY:{feature}:{limit}:exceeded` | `BUDGET_WARN_MONTHLY:my-app:scanner:d1_writes:exceeded` | 24hr | platform-usage | Monthly budget exceeded dedup |
|
|
28
|
+
| `BUDGET_WARN_MONTHLY:{feature}:{limit}:{threshold}` | `BUDGET_WARN_MONTHLY:my-app:scanner:d1_writes:70` | 24hr | platform-usage | Monthly warning threshold dedup |
|
|
29
|
+
|
|
30
|
+
## Usage & Sampling State
|
|
31
|
+
|
|
32
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
33
|
+
|---|---|---|---|---|
|
|
34
|
+
| `platform-usage:sampling-mode` | `platform-usage:sampling-mode` | None | platform-usage | Current sampling mode enum |
|
|
35
|
+
| `platform-usage:d1-writes-24h` | `platform-usage:d1-writes-24h` | None | platform-usage | Rolling 24h D1 write counter |
|
|
36
|
+
| `platform-usage:d1-writes-timestamp` | `platform-usage:d1-writes-timestamp` | None | platform-usage | Timestamp for write counter reset |
|
|
37
|
+
| `platform-usage:do-gb-seconds-24h:{project}` | `platform-usage:do-gb-seconds-24h:my-app` | None | platform-usage | DO GB-seconds per project |
|
|
38
|
+
| `platform-usage:pricing:v1` | `platform-usage:pricing:v1` | None | platform-usage | Cached pricing config |
|
|
39
|
+
| `platform-usage:prev-hour:account` | `platform-usage:prev-hour:account` | None | platform-usage | Delta calculation state |
|
|
40
|
+
| `platform-usage:prev-hour:timestamp` | `platform-usage:prev-hour:timestamp` | None | platform-usage | Last collection hour |
|
|
41
|
+
|
|
42
|
+
## Settings Cache
|
|
43
|
+
|
|
44
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
45
|
+
|---|---|---|---|---|
|
|
46
|
+
| `CONFIG:SETTINGS:ALL` | `CONFIG:SETTINGS:ALL` | 1hr | platform-usage | Full PlatformSettings JSON cache |
|
|
47
|
+
| `CONFIG:SETTINGS:{key}` | `CONFIG:SETTINGS:budget_soft_limit` | 1hr | platform-usage | Individual setting value cache |
|
|
48
|
+
|
|
49
|
+
## Error Collection (Standard+ tier)
|
|
50
|
+
|
|
51
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
52
|
+
|---|---|---|---|---|
|
|
53
|
+
| `SCRIPT_MAP:{scriptName}` | `SCRIPT_MAP:my-worker` | None | error-collector | Worker name to project mapping |
|
|
54
|
+
| `ERROR_FINGERPRINT:{hash}` | `ERROR_FINGERPRINT:a1b2c3` | None | error-collector | Cached known error state |
|
|
55
|
+
| `ISSUE_LOCK:{hash}` | `ISSUE_LOCK:a1b2c3` | 60s | error-collector | Race-condition dedup for GitHub issue creation |
|
|
56
|
+
| `TRANSIENT:{script}:{category}:{date}` | `TRANSIENT:my-worker:quota-exhausted:2026-03-02` | 24hr | error-collector | Transient error dedup window (1 issue/category/day) |
|
|
57
|
+
| `ERROR_RATE:{script}:{hour}` | `ERROR_RATE:my-worker:2026-03-02T14` | 2hr | error-collector | Hourly error rate counter |
|
|
58
|
+
|
|
59
|
+
## Sentinel (Standard+ tier)
|
|
60
|
+
|
|
61
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
62
|
+
|---|---|---|---|---|
|
|
63
|
+
| `sentinel:project-gaps:result` | `sentinel:project-gaps:result` | 1hr | platform-sentinel | Cached gap detection results |
|
|
64
|
+
| `alert-thresholds:config` | `alert-thresholds:config` | None | platform-sentinel | Alert threshold configuration |
|
|
65
|
+
|
|
66
|
+
## Gap Alerts (Standard+ tier)
|
|
67
|
+
|
|
68
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
69
|
+
|---|---|---|---|---|
|
|
70
|
+
| `GAP_ALERT:{project}:{date}` | `GAP_ALERT:my-app:2026-03-02` | 24hr | error-collector | Gap alert dedup (1 issue/project/day) |
|
|
71
|
+
|
|
72
|
+
## Pattern Discovery (Full tier)
|
|
73
|
+
|
|
74
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
75
|
+
|---|---|---|---|---|
|
|
76
|
+
| `PATTERNS:DYNAMIC:APPROVED` | `PATTERNS:DYNAMIC:APPROVED` | None (refreshed) | pattern-discovery | Approved patterns JSON cache for error-collector runtime |
|
|
77
|
+
|
|
78
|
+
## Notifications (Full tier)
|
|
79
|
+
|
|
80
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
81
|
+
|---|---|---|---|---|
|
|
82
|
+
| `NOTIFICATION_COUNT:{userId}` | `NOTIFICATION_COUNT:admin` | None | platform-notifications | Unread notification count |
|
|
83
|
+
| `NOTIFICATION_PREFS:{userId}` | `NOTIFICATION_PREFS:admin` | None | platform-notifications | User notification preferences |
|
|
84
|
+
| `NOTIFICATION_READ:{userId}:{notifId}` | `NOTIFICATION_READ:admin:abc123` | None | platform-notifications | Per-notification read state |
|
|
85
|
+
|
|
86
|
+
## Alert Dedup
|
|
87
|
+
|
|
88
|
+
| Key Pattern | Example | TTL | Worker | Purpose |
|
|
89
|
+
|---|---|---|---|---|
|
|
90
|
+
| `ALERT:{key}:last_sent` | `ALERT:my-app:scanner:last_sent` | None | platform-usage | Alert send dedup |
|
|
91
|
+
| `SLACK_ALERT:{type}:{key}` | `SLACK_ALERT:budget:my-app:scanner` | 1hr | shared/slack-alerts | Slack message dedup |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Key Conventions
|
|
96
|
+
|
|
97
|
+
- **Uppercase prefixes** (`CONFIG:`, `FEATURE:`, `BUDGET_WARN:`) = system state
|
|
98
|
+
- **Lowercase prefixes** (`platform-usage:`, `sentinel:`) = operational cache
|
|
99
|
+
- **TTL = None** means the key persists until explicitly deleted or overwritten
|
|
100
|
+
- **Dedup keys** use short TTLs (60s-24hr) to prevent duplicate actions
|
|
101
|
+
- All keys use `:` as separator (never `/` or `.`)
|
|
@@ -193,6 +193,7 @@ CREATE TABLE IF NOT EXISTS daily_usage_rollups (
|
|
|
193
193
|
|
|
194
194
|
-- Vectorize metrics
|
|
195
195
|
vectorize_queries INTEGER DEFAULT 0,
|
|
196
|
+
vectorize_inserts INTEGER DEFAULT 0,
|
|
196
197
|
vectorize_vectors_stored_max INTEGER DEFAULT 0,
|
|
197
198
|
vectorize_cost_usd REAL DEFAULT 0,
|
|
198
199
|
|