Skip to content
Patronage Ads Sync Docs
Esc
navigateopen⌘Jpreview
On this page

Architecture and boundaries

Why Ads Sync separates public contracts, reference deployment, and private dogfood operations.

Ads Sync keeps one public product promise across a package and a nested reference deployment.

operator TypeScript config
        |
        v
@patronage/ads-sync  ->  operator runner  ->  Cloudflare Containers
        |                       |                    |
        |                       v                    v
        +-----------------> Postgres <---------- Airbyte destination
                                |
                                +---- artifact metadata and committed state

operator runner  --------------------> R2 replay artifacts

The package owns typed configuration, curated provider definitions, catalog and destination helpers, state and artifact primitives, control/reporting SQL, canary validation, and historical comparison. It does not read environment variables, store credential values, persist R2 objects, authorize migrations, or create remote resources.

The reference deployment proves that an operator can import only the public package boundary and build a Worker with Wrangler. It is intentionally small. Its health and provider routes are runnable; production orchestration remains operator work.

provider tiers

Google Ads and Meta Ads are curated Supported Providers. Their definitions include pinned Airbyte source images, backfill defaults, rate limit policy, default schemas, and reporting views. This is the maintained product surface.

defineProvider() exposes the shape for an advanced custom definition. A custom provider still needs an operator-owned catalog, Dockerfile, Container class, policies, and reporting work. The generic helper is not a promise that Ads Sync supports every Airbyte source.

storage and lifecycle

Cloudflare Workers, Containers, Workflows, and R2 define the deployment identity. Standard reachable Postgres is the database contract. Hyperdrive is a reference Worker read path, while destination Containers write to Postgres directly.

Desired state belongs in TypeScript config. Postgres owns mutable runtime state such as Sync Connections, Backfill Plans, Sync Run Windows, committed cursors, generations, artifact metadata, and leases. R2 holds replay artifacts at keys derived from provider, stream, and run id.

Each enabled Sync Connection gets an isolated Airbyte Direct Load schema. This avoids collisions in Airbyte generation and state behavior when accounts or catalogs multiply.

canary, backfill, and comparison

A canary is one exact connection over no more than 24 hours. It limits the first live proof and gives the operator a canonical request hash.

A Backfill Plan divides history into durable bounded windows. Provider defaults limit step size and work per run; an operator runner owns scheduling, lease handling, retries, cooldowns, and status.

The Historical Comparison Gate checks stable campaign/day provider data against the reporting view. It is the reporting-correctness launch evidence, separate from live sidecar accumulation.

See the runnable prepare-bounded-run.ts and run-historical-comparison.ts source tutorials.

public and private dogfood

src/packages/ads-sync is born-clean public release source. The deterministic release process mirrors it to packages/ads-sync and applies privacy checks.

apps/ads-sync is Patronage’s private operator deployment. It proves the public imports against real Workflows, Containers, Postgres, R2, canary controls, backfill orchestration, and operational safety. It is evidence, not release source, and its private routes, bindings, credentials, infrastructure names, and maintenance commands are not public package capabilities.

Was this page helpful?