feat(batch-export): manage batch exports as code (secrets convention) - #100
Open
pl wants to merge 2 commits into
Open
feat(batch-export): manage batch exports as code (secrets convention)#100pl wants to merge 2 commits into
pl wants to merge 2 commits into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds batch exports (
projects/{id}/batch_exports) as a managed resource — the campaign's first secret-bearing resource, establishing the sharedsecret()helper on this base.Design
name(no description/tags — dropped by the serializer). Declarativepaused;interval/model/filters/timezoneround-trip.src/resources/secret.ts): destination credentials aresecret("ENV_VAR"), resolved fromprocess.envat apply time. The value never enters a file or the hash — only the env-var name + optionalrotatetoken are hashed, so PostHog's masked read-back (secret fields stripped fromconfig) never dirties a no-op. A missing env var fails loud before any write. Rotate by bumping the token.AwsS3/S3Compatible/Snowflake. Integration-backed types (Databricks / AzureBlob / BigQuery / Postgres / Redshift) are rejected with a clear validation error (they require a project-specificintegration_idthat doesn't port across projects).PATCH+ realDELETE(204).destinationis a typed passthrough bag.Verification (dev project 806, paused + obviously-fake creds)
create (paused,
latest_runs=0— no 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 directpruneBatchExport. All rows deleted; no export run was ever created. Gates:typecheck/typecheck:examples/lint/test(302) pass.Notes for review
src/resources/secret.tsis a new shared helper. Hog functions ship their ownsecret()(__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 tomasterwhen #81 merges. First commit is the codegen regen (skippable in review).docs/resources.mdrow flipped;#78carries the full matrix refresh.🤖 Generated with Claude Code