Skip to content

feat(batch-export): manage batch exports as code (secrets convention) - #100

Open
pl wants to merge 2 commits into
pl/spec-migrationfrom
pl/resource-batch-exports
Open

feat(batch-export): manage batch exports as code (secrets convention)#100
pl wants to merge 2 commits into
pl/spec-migrationfrom
pl/resource-batch-exports

Conversation

@pl

@pl pl commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Adds batch exports (projects/{id}/batch_exports) as a managed resource — the campaign's first secret-bearing resource, establishing the shared secret() helper on this base.

Design

  • Identity: marker in name (no description/tags — dropped by the serializer). Declarative paused; interval/model/filters/timezone round-trip.
  • Secrets (feat(hog-function): SDK factory + pipeline + secrets convention #89 convention, factored into src/resources/secret.ts): destination credentials are secret("ENV_VAR"), resolved from process.env at apply time. The value never enters a file or the hash — only the env-var name + optional rotate token are hashed, so PostHog's masked read-back (secret fields stripped from config) never dirties a no-op. A missing env var fails loud before any write. Rotate by bumping the token.
  • Supported destinations: inline-credential types only — AwsS3 / S3Compatible / Snowflake. Integration-backed types (Databricks / AzureBlob / BigQuery / Postgres / Redshift) are rejected with a clear validation error (they require a project-specific integration_id that doesn't port across projects).
  • Real PATCH + real DELETE (204). destination is a typed passthrough bag.
  • Excluded from the smoke seed: a secret resource can't round-trip through pull (creds are masked), so the pull→re-apply no-op assertion can't hold (subscriptions precedent).

Verification (dev project 806, paused + obviously-fake creds)

create (paused, latest_runs=0no run triggered) → no-op re-apply (masked secret does NOT dirty it) → edit prefix/region + rotate token → single update → no-op → missing-env-var apply fails loud pre-write → orphan left untouched → hand-built row (no marker) invisible to plan/orphans (safety invariant) → scoped prune via direct pruneBatchExport. All rows deleted; no export run was ever created. Gates: typecheck / typecheck:examples / lint / test (302) pass.

Notes for review

  • src/resources/secret.ts is a new shared helper. Hog functions ship their own secret() (__hogSecret) on a separate unmerged branch — these should converge on the shared helper when that lands (flagged in the commit).

Stacking

Stacks on #81 (pl/spec-migration, codegen-only base). Retarget to master when #81 merges. First commit is the codegen regen (skippable in review). docs/resources.md row flipped; #78 carries the full matrix refresh.

🤖 Generated with Claude Code

pl and others added 2 commits July 24, 2026 10:01
Add batch_exports list/create/retrieve/partial_update/destroy to the
openapi-filter allowlist and regenerate src/generated/api.d.ts. pause/unpause
endpoints are omitted — the client drives the declarative `paused` field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Manage batch exports (projects/{id}/batch_exports) as code — the first
secret-bearing resource on this base. Identity marker in `name`; declarative
`paused`; `interval`/`model`/`filters`/`timezone` round-trip.

Secrets: destination credentials are declared as secret("ENV_VAR") and resolved
from process.env at apply time (the #89 convention, factored into a shared
src/resources/secret.ts). The value never enters a file or the hash — only the
env-var name + optional rotate token are hashed, so PostHog's masked read-back
never dirties a no-op (live-verified). A missing env var fails loud before any
write. Inline-credential destinations only (AwsS3/S3Compatible/Snowflake);
integration-backed types (Databricks/AzureBlob/BigQuery/Postgres/Redshift) are
rejected with a clear validation error (they need a non-portable integration_id).
Real PATCH + real DELETE (204). Excluded from the smoke seed: a secret resource
can't round-trip through pull, so the no-op assertion can't hold (subscriptions
precedent).

Note: hog functions ship their own secret() (__hogSecret) on a separate branch;
these should converge on the shared helper when that lands.

Includes pull codegen (renders masked config + a fill-in-secrets warning), unit
tests (secret hash-exclusion, rotate, unsupported-destination rejection), two
examples, README scope (batch_export:read/write), resources.md row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pl added a commit that referenced this pull request Jul 24, 2026
Logs sampling rules (#97), warehouse saved queries (#99), and batch
exports (#100) complete the buildable surface. Logs alerts/metric rules,
warehouse tables/view links deferred; group types excluded; notebooks
parked. Adds a status section with the post-merge follow-up list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant