@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 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 Flags (non-interactive)
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
- +-- platform/config/
49
- | +-- services.yaml # Project registry, feature definitions
50
- | +-- budgets.yaml # Daily limits, circuit breaker thresholds
51
- +-- storage/d1/migrations/ # D1 schema (4 core migrations + seed)
52
- +-- workers/
53
- | +-- platform-usage.ts # Data warehouse worker (cron + queue consumer)
54
- | +-- lib/ # Shared libraries (billing, analytics, budgets)
55
- +-- scripts/
56
- | +-- sync-config.ts # Sync YAML config to D1/KV
57
- +-- wrangler.*.jsonc # Worker configs with binding placeholders
58
- +-- package.json
59
- +-- tsconfig.json
60
- +-- README.md
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
- - `workers/error-collector.ts` Tail worker that creates GitHub issues from errors
66
- - `workers/platform-sentinel.ts` — Gap detection, cost monitoring, alerts
67
- - `workers/lib/error-collector/`Fingerprinting, deduplication, digest
68
- - `workers/lib/sentinel/` Project gap detection
69
- - `storage/d1/migrations/005_error_collection.sql`
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
- - `workers/pattern-discovery.ts` AI-assisted transient error pattern discovery
74
- - `workers/platform-alert-router.ts` — Unified alert normalisation and routing
75
- - `workers/platform-notifications.ts` In-app notification API
76
- - `workers/platform-search.ts` Full-text search (FTS5)
77
- - `workers/platform-settings.ts` Settings management API
78
- - `workers/lib/pattern-discovery/` Clustering, AI prompts, validation, shadow eval
79
- - `storage/d1/migrations/006_pattern_discovery.sql`
80
- - `storage/d1/migrations/007_notifications_search.sql`
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
- # Create Cloudflare resources
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
- # Update resource IDs in wrangler.*.jsonc, then:
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
- ## Updating Your Platform
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
- Starting with v1.1.0, the Admin SDK writes a `.platform-scaffold.json` manifest that tracks what was generated. This enables safe, incremental upgrades.
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
- ### Upgrade an existing project
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 to avoid conflicts with your own
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
- ### Adopt a pre-v1.1.0 project
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
- This hashes your existing files as a baseline and writes `.platform-scaffold.json`. You can then run `upgrade` normally.
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` — the Consumer SDK. Install it in your application workers to send telemetry to the platform backend:
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
- See the [Consumer SDK README](../consumer-sdk/README.md) for integration details.
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
- ## License
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 = {};
@@ -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.1.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.1.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.1.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';
@@ -329,6 +329,7 @@ export async function refreshDynamicPatternsCache(
329
329
  FROM transient_pattern_suggestions
330
330
  WHERE status = 'approved'
331
331
  ORDER BY created_at ASC
332
+ LIMIT 500
332
333
  `
333
334
  )
334
335
  .all<PatternRule & { id: string }>();
@@ -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