From 1f47dc8c8a13169674cffa4cc3193a0d5767a443 Mon Sep 17 00:00:00 2001 From: Yaacov Date: Tue, 8 Sep 2026 19:30:16 +0300 Subject: [PATCH] feat(analytics): prepare observable production gateway --- README.md | 8 +++++--- workers/events/src/index.test.ts | 4 ++++ workers/events/src/index.ts | 10 +++++++++- workers/events/worker-configuration.d.ts | 15 +++++++++++++-- workers/events/wrangler.jsonc | 7 +++++++ 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4b860b8..a773bf6 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,8 @@ bun run events:deploy are Cloudflare Worker secrets and must never be committed. The personal key is used only for queued deletion and needs the reviewed person read/write scopes for lookup, submission, and verification (qualify the exact provider permissions); -`POSTHOG_PROJECT_ID` selects the project. If the project token is absent, +`POSTHOG_PROJECT_ID` selects the project and is committed as non-secret Worker +configuration. If the project token is absent, ingestion continues and events remain queued in D1 for later delivery. If the deletion key or project ID is absent, accepted erasures remain queued in D1. If the identity-link token is absent, account linking returns `503` while ordinary @@ -193,8 +194,9 @@ Before activating an owner-approved rollout: 1. Apply the approved migrations and deploy the reviewed Worker with **both desktop gates false**. Website Pages deployment is not Worker deployment. 2. Verify `/health` against the exact deployed revision: required schema and a - recent successful retention pass are checked, but configured secrets are not - proof of valid permissions. + recent successful retention pass are checked, and the Worker version ID, tag, + and creation time identify the deployed artifact. Configured secrets are not + proof of valid permissions. Tag production uploads with the reviewed Git commit. 3. Confirm the approved first-party-only diagnostic routing and truthful PostHog-managed retention wording. Verify asynchronous provider erasure with synthetic identifiers; an arbitrary delay or repeat-delete loop is not proof. diff --git a/workers/events/src/index.test.ts b/workers/events/src/index.test.ts index e52e97a..248ff34 100644 --- a/workers/events/src/index.test.ts +++ b/workers/events/src/index.test.ts @@ -368,6 +368,10 @@ describe("event gateway routes", () => { expect(response.status).toBe(200); expect(await response.json()).toMatchObject({ status: "ready", + contract_revision: "3", + worker_version: "unavailable", + worker_version_tag: null, + worker_version_created_at: null, storage: "ready", retention: "pending_verification", activation_prerequisites_configured: false, diff --git a/workers/events/src/index.ts b/workers/events/src/index.ts index 403ee3f..a75996a 100644 --- a/workers/events/src/index.ts +++ b/workers/events/src/index.ts @@ -25,9 +25,14 @@ const RETENTION_BATCH_SIZE = 5_000; type AnalyticsEnv = Omit< AnalyticsWorkerBindings, | "ANALYTICS_INGESTION_RATE_LIMITER" + | "CF_VERSION_METADATA" | "DESKTOP_INGESTION_ENABLED" | "DESKTOP_POSTHOG_EXPORT_ENABLED" + | "POSTHOG_PERSONAL_API_KEY" + | "POSTHOG_PROJECT_ID" + | "POSTHOG_PROJECT_TOKEN" > & { + readonly CF_VERSION_METADATA?: WorkerVersionMetadata; readonly POSTHOG_PROJECT_TOKEN?: string; readonly POSTHOG_PERSONAL_API_KEY?: string; readonly POSTHOG_PROJECT_ID?: string; @@ -1161,7 +1166,10 @@ const worker: ExportedHandler = { return jsonResponse( { status: storageReady ? "ready" : "degraded", - contract_revision: "2", + contract_revision: "3", + worker_version: env.CF_VERSION_METADATA?.id ?? "unavailable", + worker_version_tag: env.CF_VERSION_METADATA?.tag ?? null, + worker_version_created_at: env.CF_VERSION_METADATA?.timestamp ?? null, storage: storageReady ? "ready" : "unavailable_or_unmigrated", retention: retentionReady ? "recent_success" : "pending_verification", activation_prerequisites_configured: Boolean( diff --git a/workers/events/worker-configuration.d.ts b/workers/events/worker-configuration.d.ts index a332b56..6e8e387 100644 --- a/workers/events/worker-configuration.d.ts +++ b/workers/events/worker-configuration.d.ts @@ -1,10 +1,14 @@ /* eslint-disable */ -// Generated by Wrangler by running `wrangler types --config=workers/events/wrangler.jsonc --include-runtime=false --env-interface=AnalyticsWorkerBindings workers/events/worker-configuration.d.ts` (hash: ec6c211557aaf856bf40f03bf0d7023a) +// Generated by Wrangler by running `wrangler types --config=workers/events/wrangler.jsonc --include-runtime=false --env-interface=AnalyticsWorkerBindings workers/events/worker-configuration.d.ts` (hash: ee9d44a6ab6f6fd522cbd77158166bc2) interface __BaseEnv_AnalyticsWorkerBindings { ANALYTICS_DB: D1Database; ANALYTICS_INGESTION_RATE_LIMITER: RateLimit; + CF_VERSION_METADATA: WorkerVersionMetadata; DESKTOP_INGESTION_ENABLED: "false"; DESKTOP_POSTHOG_EXPORT_ENABLED: "false"; + POSTHOG_PROJECT_ID: "228610"; + POSTHOG_PROJECT_TOKEN: string; + POSTHOG_PERSONAL_API_KEY: string; } declare namespace Cloudflare { interface GlobalProps { @@ -18,6 +22,13 @@ type StringifyValues> = { }; declare namespace NodeJS { interface ProcessEnv extends StringifyValues< - Pick + Pick< + Cloudflare.Env, + | "DESKTOP_INGESTION_ENABLED" + | "DESKTOP_POSTHOG_EXPORT_ENABLED" + | "POSTHOG_PROJECT_ID" + | "POSTHOG_PROJECT_TOKEN" + | "POSTHOG_PERSONAL_API_KEY" + > > {} } diff --git a/workers/events/wrangler.jsonc b/workers/events/wrangler.jsonc index 5dde4e4..cfe27c9 100644 --- a/workers/events/wrangler.jsonc +++ b/workers/events/wrangler.jsonc @@ -7,6 +7,13 @@ "vars": { "DESKTOP_INGESTION_ENABLED": "false", "DESKTOP_POSTHOG_EXPORT_ENABLED": "false", + "POSTHOG_PROJECT_ID": "228610", + }, + "secrets": { + "required": ["POSTHOG_PROJECT_TOKEN", "POSTHOG_PERSONAL_API_KEY"], + }, + "version_metadata": { + "binding": "CF_VERSION_METADATA", }, "routes": [ {