Skip to content

Remove ControlPlane (pgflow edge function) — startup compilation makes it redundant #647

Description

@jumski

title: Remove ControlPlane (pgflow edge function) — startup compilation makes it redundant
labels: enhancement, pkgs/edge-worker, pkgs/cli, pkgs/website

Summary

Drop the ControlPlane (supabase/functions/pgflow/index.tsControlPlane.serve(flows)), its pgflow compile CLI command, and all supporting code/docs. Startup compilation covers everything the ControlPlane does, works reliably, and is already the documented preferred path.

Docs already pre-announce this: manual-compilation.mdx and compile-api.mdx both carry a deprecation notice — "Manual compilation via ControlPlane may be removed in a future release. Startup Compilation is the preferred approach."

What ControlPlane actually is

ControlPlane.serve(flows) starts a Deno.serve HTTP handler exposing a single endpoint:

GET /flows/:slug  →  compileFlow(flow)  →  { flowSlug, sql: string[] }

Code: pkgs/edge-worker/src/control-plane/ (index.ts, server.ts).

Exactly one consumer exists: the pgflow compile CLI command (pkgs/cli/src/commands/compile/index.ts), which fetches SQL from the endpoint and writes a timestamped migration file supabase/migrations/{timestamp}_create_{slug}_flow.sql.

No other caller found: no CI workflows, no examples, no runtime path. Worker management (ensure_workers() cron + track_worker_function) pings worker functions, never the pgflow function. deploy-first-flow.mdx already states the ControlPlane function "is for local compilation only and is not needed in production."

Why startup compilation fully covers it

FlowWorkerLifecycle.acknowledgeStart()Queries.ensureFlowCompiled()pgflow.ensure_flow_compiled() (pkgs/core/schemas/0100_function_ensure_flow_compiled.sql) is complete and safe:

  • advisory lock (pg_advisory_xact_lock) serializes concurrent worker starts for the same flow
  • flow missing → compiled (both environments)
  • shape match → verified
  • shape mismatch → local or allowDataLoss: true → delete + recompile; production → mismatch → worker throws FlowShapeMismatchError and refuses to start

The versioned-flow workflow (build/version-flows.mdx) also works without migrations: a versioned flow (greetUserV2) is a new slug → "missing" → compiled at startup, even in production. The only prohibited case (mutating an existing flow's shape) is blocked by ensure_flow_compiled itself.

The get-started tutorial (quickstart, create-flow, run-flow) is 100% startup-compilation based already.

Removal checklist

pkgs/cli

  • Delete src/commands/compile/ and its tests (__tests__/commands/compile/, __tests__/e2e/compile.test.ts)
  • Remove create-edge-function.ts step from install (command + its test + summary line "Create Control Plane in supabase/functions/pgflow/")
  • Update README.md (compile command section)

pkgs/edge-worker

  • Delete src/control-plane/
  • Remove export from src/index.ts (export { ControlPlane } from './control-plane/index.js')
  • Delete tests: tests/unit/control-plane/, tests/e2e/control-plane.test.ts
  • Delete supabase/functions/pgflow/ (e2e harness); _vendor/ copies shrink on next vendor sync

apps/demo

  • Delete supabase/functions/pgflow/index.ts

pkgs/website

  • Delete concepts/manual-compilation.mdx
  • Delete reference/control-plane-api.mdx
  • Fix reference/compile-api.mdx (drop CLI mentions; compileFlow() itself stays)
  • Rewrite build/version-flows.mdx step 2: "deploy the worker — startup compilation creates the flow"
  • Remove ControlPlane note from deploy/supabase/deploy-first-flow.mdx
  • Fix reference/index.mdx

pkgs/dsl

  • Stale comment fix: src/flow-shape.ts references "Used by ControlPlane"

Caveats

  1. Migration-file workflow is lost. Teams putting flow SQL in source control for CI review lose pgflow compile. Mitigation exists and is documented: compileFlow() from @pgflow/dsl (published to npm, runs in Node). With startup compilation the schema changes at worker boot, not via reviewed migration — a philosophical regression for strict CI shops, a non-issue for everyone else. This is the only substantive trade-off.
  2. Breaking change accounting. ControlPlane is a public export of @pgflow/edge-worker (JSR + npm) — semver-major for that package. Old CLIs (pgflow@0.90.15 compile) run against a freshly installed project will fail, but they already fail gracefully with their own "ControlPlane edge function not found" message. Existing installs keep a harmless leftover supabase/functions/pgflow/ directory. Both deserve a line in the release notes; neither blocks removal.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions