These commits are when the Protocol Buffers files have changed: (only the last 100 relevant commits are shown)
| Commit: | 598d7fb | |
|---|---|---|
| Author: | Oz | |
| Committer: | ogzhanolguncu | |
feat(api): create deployment endpoint (#6617) * feat(api): create deployment endpoint * fix: generation * feat: add handler and tests * refactor: move audit logging to rpc and clean up callers * refactor: change ui permissions and remove old endpoints * fix: redeploy bug and add missing fork on redeploy * chore: tidy * refactor: prevent leaking internals * chore: refine comment * revert: restore old endpoint and mark them as deprecated instead * revert: rest of the removed
| Commit: | 19c39d3 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) Set Resend Idempotency-Key on budget alert sends so a retried Restate step does not double-email after a transient failure that still reached Resend.
| Commit: | 4a15e4b | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904)
| Commit: | 6a4c7c1 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | 5a80184 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923) Suspend/resume via teardown, wake gate, dashboard meter parity, and deploy_spend_check integration test (requires DeployTeardownService).
| Commit: | b1ae472 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922)
| Commit: | 86b6285 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl)!: per-workspace push invocations for deploy billing Resolve close.go rebase conflict with eng-2865: keep fanout push/finalize flow and eng-2865 defer-on-close-failure behavior (no customer-scoped fallback).
| Commit: | 0f131bc | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Stripe invoice.created webhook on ctrl-api plus backup cron to push final period usage and finalize renewal drafts. Bounded retries with Kill on exhaustion, per-workspace defer on close failures, skip when subscription id is missing. Midnight-UTC anchor at Deploy checkout; no migration needed.
| Commit: | 264e35c | |
|---|---|---|
| Author: | Oz | |
| Committer: | ogzhanolguncu | |
feat(api): create deployment endpoint (#6617) * feat(api): create deployment endpoint * fix: generation * feat: add handler and tests * refactor: move audit logging to rpc and clean up callers * refactor: change ui permissions and remove old endpoints * fix: redeploy bug and add missing fork on redeploy * chore: tidy * refactor: prevent leaking internals * chore: refine comment * revert: restore old endpoint and mark them as deprecated instead * revert: rest of the removed
| Commit: | b0fbe85 | |
|---|---|---|
| Author: | Oz | |
| Committer: | ogzhanolguncu | |
feat(api): create deployment endpoint (#6617) * feat(api): create deployment endpoint * fix: generation * feat: add handler and tests * refactor: move audit logging to rpc and clean up callers * refactor: change ui permissions and remove old endpoints * fix: redeploy bug and add missing fork on redeploy * chore: tidy * refactor: prevent leaking internals * chore: refine comment * revert: restore old endpoint and mark them as deprecated instead * revert: rest of the removed
| Commit: | 36580f7 | |
|---|---|---|
| Author: | James | |
Make slack dedupe and installed workspace wide so each project can have a channel. Make it easier to configure.
| Commit: | c917dee | |
|---|---|---|
| Author: | James | |
fix: slack approved
| Commit: | f7d88b8 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923) Suspend/resume via teardown, wake gate, dashboard meter parity, and deploy_spend_check integration test (requires DeployTeardownService).
| Commit: | 8840f3a | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | a3ba757 | |
|---|---|---|
| Author: | James | |
init: make slack notifications great
| Commit: | 731790d | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922) Adds the DeployTeardownService virtual object: it snapshots a workspace's running deployments, clears apps.current_deployment_id, and schedules archive or standby with drain polling. SUSPEND records the running set so a later resume can restore it. Also removes svc/ctrl/integration/sync_test.go, which stopped compiling after the harness changes and is not re-added here.
| Commit: | 51a392c | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904)
| Commit: | 366d4c5 | |
|---|---|---|
| Author: | Oz | |
| Committer: | ogzhanolguncu | |
feat(api): create deployment endpoint (#6617) * feat(api): create deployment endpoint * fix: generation * feat: add handler and tests * refactor: move audit logging to rpc and clean up callers * refactor: change ui permissions and remove old endpoints * fix: redeploy bug and add missing fork on redeploy * chore: tidy * refactor: prevent leaking internals * chore: refine comment * revert: restore old endpoint and mark them as deprecated instead * revert: rest of the removed
| Commit: | 246bcb7 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922) Adds the DeployTeardownService virtual object: it snapshots a workspace's running deployments, clears apps.current_deployment_id, and schedules archive or standby with drain polling. SUSPEND records the running set so a later resume can restore it. Also removes svc/ctrl/integration/sync_test.go, which stopped compiling after the harness changes and is not re-added here.
| Commit: | 5c9204e | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923) Suspend/resume via teardown, wake gate, dashboard meter parity, and deploy_spend_check integration test (requires DeployTeardownService).
| Commit: | 6c89414 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | 430fc6e | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl)!: per-workspace push invocations for deploy billing Not behavior-preserving. The hourly push and month-end close now fan out one Restate invocation per workspace instead of pushing inline, so each push retries and fails in isolation: one workspace's broken Stripe state no longer stalls the others or the tick. The close awaits its pushes and, when any fail, leaves those workspaces' invoices open and returns a TerminalError so the fresh-key backup cron genuinely re-pushes them rather than finalizing an under-billed total. The close also gates finalization on two durable sleeps: a 15-minute ingestion buffer after the period ends before the final ClickHouse read (late rows would otherwise be permanently unbilled once the invoice finalizes), and a 20-minute wait between the final meter push and finalization so Stripe has aggregated the events into the draft's metered lines. DEPLOY NOTE: this changes the journaled step sequence of RunDeployBillingPush and RunDeployBillingClose. Drain in-flight deploy-billing invocations before deploying, or old journals may fail replay.
| Commit: | bcaadb4 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | e0b5647 | |
|---|---|---|
| Author: | chronark | |
Merge remote-tracking branch 'origin/main' into worktree-delayed-soft-deletes # Conflicts: # dev/k8s/charts/restate-cronjobs/values.yaml # docs/engineering/docs.json # gen/proto/ctrl/v1/project.pb.go # gen/proto/hydra/v1/app.pb.go # gen/proto/hydra/v1/cron.pb.go # gen/proto/hydra/v1/cron_restate.pb.go # gen/proto/hydra/v1/environment.pb.go # gen/proto/hydra/v1/project.pb.go # pkg/db/BUILD.bazel # pkg/db/app_find_with_settings.sql_generated.go # pkg/db/app_list_by_project.sql_generated.go # pkg/db/github_repo_connection_list_deploy_context.sql_generated.go # pkg/db/project_find_by_workspace_slug.sql_generated.go # pkg/db/querier_generated.go # pkg/db/queries/app_list_by_project.sql # pkg/db/queries/project_find_by_workspace_slug.sql # svc/ctrl/api/run.go # svc/ctrl/proto/hydra/v1/app.proto # svc/ctrl/proto/hydra/v1/cron.proto # svc/ctrl/proto/hydra/v1/environment.proto # svc/ctrl/proto/hydra/v1/project.proto # svc/ctrl/services/app/delete_app.go # svc/ctrl/services/project/BUILD.bazel # svc/ctrl/services/project/delete_project.go # svc/ctrl/services/project/service.go # svc/ctrl/worker/app/delete_permanently_handler.go # svc/ctrl/worker/cron/BUILD.bazel # svc/ctrl/worker/cron/cron.go # svc/ctrl/worker/environment/delete_permanently_handler.go # svc/ctrl/worker/project/delete_handler.go # svc/ctrl/worker/run.go # web/apps/dashboard/components/navigation/sidebar-v2/sidebar-body.tsx # web/apps/dashboard/gen/proto/ctrl/v1/project_pb.ts # web/apps/dashboard/lib/flags/index.ts # web/apps/dashboard/lib/flags/resolve.ts # web/apps/dashboard/lib/navigation/leaves.ts # web/apps/dashboard/lib/trpc/routers/index.ts
| Commit: | 405bb06 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
refactor: move audit logging to rpc and clean up callers
| Commit: | 793f7f1 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923) Suspend/resume via teardown, wake gate, dashboard meter parity, and deploy_spend_check integration test (requires DeployTeardownService).
| Commit: | 6aa0c1b | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | 264f13b | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922) Adds the DeployTeardownService virtual object: it snapshots a workspace's running deployments, clears apps.current_deployment_id, and schedules archive or standby with drain polling. SUSPEND records the running set so a later resume can restore it. Also removes svc/ctrl/integration/sync_test.go, which stopped compiling after the harness changes and is not re-added here.
| Commit: | 19d0e5b | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron, workos client, deployspendcheck package, orchestrator integration test, and deployCredits tests. Drop deploy_spend_check integration test from this PR; it needs DeployTeardownService (ENG-2922+).
| Commit: | 4837684 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl)!: per-workspace push invocations for deploy billing Not behavior-preserving. The hourly push and month-end close now fan out one Restate invocation per workspace instead of pushing inline, so each push retries and fails in isolation: one workspace's broken Stripe state no longer stalls the others or the tick. The close awaits its pushes and, when any fail, leaves those workspaces' invoices open and returns a TerminalError so the fresh-key backup cron genuinely re-pushes them rather than finalizing an under-billed total. The close also gates finalization on two durable sleeps: a 15-minute ingestion buffer after the period ends before the final ClickHouse read (late rows would otherwise be permanently unbilled once the invoice finalizes), and a 20-minute wait between the final meter push and finalization so Stripe has aggregated the events into the draft's metered lines. DEPLOY NOTE: this changes the journaled step sequence of RunDeployBillingPush and RunDeployBillingClose. Drain in-flight deploy-billing invocations before deploying, or old journals may fail replay.
| Commit: | ea20455 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | a92a44c | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923)
| Commit: | 9441965 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | 80ca44e | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922) Adds the DeployTeardownService virtual object: it snapshots a workspace's running deployments, clears apps.current_deployment_id, and schedules archive or standby with drain polling. SUSPEND records the running set so a later resume can restore it. Also removes svc/ctrl/integration/sync_test.go, which stopped compiling after the harness changes and is not re-added here.
| Commit: | a122957 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md
| Commit: | f7d71a5 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl)!: per-workspace push invocations for deploy billing Not behavior-preserving. The hourly push and month-end close now fan out one Restate invocation per workspace instead of pushing inline, so each push retries and fails in isolation: one workspace's broken Stripe state no longer stalls the others or the tick. The close awaits its pushes and, when any fail, leaves those workspaces' invoices open and returns a TerminalError so the fresh-key backup cron genuinely re-pushes them rather than finalizing an under-billed total. The close also gates finalization on two durable sleeps: a 15-minute ingestion buffer after the period ends before the final ClickHouse read (late rows would otherwise be permanently unbilled once the invoice finalizes), and a 20-minute wait between the final meter push and finalization so Stripe has aggregated the events into the draft's metered lines. DEPLOY NOTE: this changes the journaled step sequence of RunDeployBillingPush and RunDeployBillingClose. Drain in-flight deploy-billing invocations before deploying, or old journals may fail replay.
| Commit: | c96c91b | |
|---|---|---|
| Author: | James P | |
| Committer: | GitHub | |
feat: allow ratelimit configuration for keys (#6562) * feat: allow ratelimit configuration for keys * implement union with some refining * remove required
| Commit: | 65142cf | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | 3ecbefa | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923)
| Commit: | aa56584 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | 5394fd0 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md
| Commit: | 0b1144c | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922) Adds the DeployTeardownService virtual object: it snapshots a workspace's running deployments, clears apps.current_deployment_id, and schedules archive or standby with drain polling. SUSPEND records the running set so a later resume can restore it. Also removes svc/ctrl/integration/sync_test.go, which stopped compiling after the harness changes and is not re-added here.
| Commit: | 71c119b | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl)!: per-workspace push invocations for deploy billing Not behavior-preserving. The hourly push and month-end close now fan out one Restate invocation per workspace instead of pushing inline, so each push retries and fails in isolation: one workspace's broken Stripe state no longer stalls the others or the tick. The close awaits its pushes and, when any fail, leaves those workspaces' invoices open and returns a TerminalError so the fresh-key backup cron genuinely re-pushes them rather than finalizing an under-billed total. The close also gates finalization on two durable sleeps: a 15-minute ingestion buffer after the period ends before the final ClickHouse read (late rows would otherwise be permanently unbilled once the invoice finalizes), and a 20-minute wait between the final meter push and finalization so Stripe has aggregated the events into the draft's metered lines. DEPLOY NOTE: this changes the journaled step sequence of RunDeployBillingPush and RunDeployBillingClose. Drain in-flight deploy-billing invocations before deploying, or old journals may fail replay.
| Commit: | 3d0fcb0 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | 1546a98 | |
|---|---|---|
| Author: | Oz | |
| Committer: | GitHub | |
feat(api): add app delete endpoint (#6502) * feat(api): add app delete endpoint * fix: accept both slug and id * fix: correlation id and retryable auditlogs * fix: permissions and tests * chore: tidy
| Commit: | 2f35562 | |
|---|---|---|
| Author: | James P | |
| Committer: | GitHub | |
Merge branch 'main' into perkinsjr/eng-2979-allow-configuring-sentinel-policy-rate
| Commit: | 9a52e6b | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923)
| Commit: | 4f203b9 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | 7b20494 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922) Adds the DeployTeardownService virtual object: it snapshots a workspace's running deployments, clears apps.current_deployment_id, and schedules archive or standby with drain polling. SUSPEND records the running set so a later resume can restore it. Also removes svc/ctrl/integration/sync_test.go, which stopped compiling after the harness changes and is not re-added here.
| Commit: | 393c67f | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md
| Commit: | bcee0d1 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl)!: per-workspace push invocations for deploy billing Not behavior-preserving. The hourly push and month-end close now fan out one Restate invocation per workspace instead of pushing inline, so each push retries and fails in isolation: one workspace's broken Stripe state no longer stalls the others or the tick. The close awaits its pushes and, when any fail, leaves those workspaces' invoices open and returns a TerminalError so the fresh-key backup cron genuinely re-pushes them rather than finalizing an under-billed total.
| Commit: | 0f74434 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | 2bc349a | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
fix: correlation id and retryable auditlogs
| Commit: | 43ef8e1 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
feat(api): add app delete endpoint
| Commit: | 743c25b | |
|---|---|---|
| Author: | James P | |
| Committer: | GitHub | |
feat: Allow custom build commands for railpack (#6583) * Railpack config for builds and installs * fix: remove install * Fix: Remove the install error
| Commit: | aded925 | |
|---|---|---|
| Author: | James | |
fix: remove install
| Commit: | 0ef7dfe | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
fix: correlation id and retryable auditlogs
| Commit: | e595899 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
feat(api): add app delete endpoint
| Commit: | 44d9c73 | |
|---|---|---|
| Author: | James | |
Railpack config for builds and installs
| Commit: | c32d40d | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923)
| Commit: | 9a8d4d3 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy teardown service (ENG-2922) Adds the DeployTeardownService virtual object: it snapshots a workspace's running deployments, clears apps.current_deployment_id, and schedules archive or standby with drain polling. SUSPEND records the running set so a later resume can restore it. Also removes svc/ctrl/integration/sync_test.go, which stopped compiling after the harness changes and is not re-added here.
| Commit: | ab519bf | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | b7d22e7 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md
| Commit: | d5971e6 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl)!: per-workspace push invocations for deploy billing Not behavior-preserving. The hourly push and month-end close now fan out one Restate invocation per workspace instead of pushing inline, so each push retries and fails in isolation: one workspace's broken Stripe state no longer stalls the others or the tick. The close awaits its pushes and, when any fail, leaves those workspaces' invoices open and returns a TerminalError so the fresh-key backup cron genuinely re-pushes them rather than finalizing an under-billed total.
| Commit: | d023aaf | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | ab2b45b | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
fix: correlation id and retryable auditlogs
| Commit: | dc9bc67 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
feat(api): add app delete endpoint
| Commit: | 73f569c | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923)
| Commit: | bdedbb2 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | 0741848 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl,frontline): Deploy teardown service + offline 503 (ENG-2922)
| Commit: | edea2d1 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md
| Commit: | a164652 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl): per-workspace push invocations for deploy billing Replace the journaled-batch push (one big invocation, per-workspace failures recorded as a bool) with a fan-out to DeployBillingPushService: the orchestrator resolves billable workspaces and dispatches one push invocation per workspace, keyed by workspace id. Each push retries and fails in isolation as its own visible invocation and returns a real error. Hourly orchestrator fires-and-forgets; the month-end close awaits the pushes so the closing invoice sees the final total before finalizing.
| Commit: | 94dffb3 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | dfbaef3 | |
|---|---|---|
| Author: | James | |
feat: allow ratelimit configuration for keys
| Commit: | 0794235 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
fix: correlation id and retryable auditlogs
| Commit: | a2e0115 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
feat(api): add app delete endpoint
| Commit: | a139754 | |
|---|---|---|
| Author: | Oz | |
| Committer: | GitHub | |
feat(api): add app create endpoint (#6489) * feat(dashboard): add app create * refactor: revert rbac coz ui doesn't know how to handle it * refactor: move audit to ctrl api * fix: use actor * refactor: use projectId instead of projectSlug * fix: permission explanation we are still using the old convention * refactor: use project slug instead of projectId * fix: create app accept both project id and slug * fix: adjust query name * fix: openapi schema * chore: tidy permission ui * fix: regex and permission
| Commit: | 1ee9c9c | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl,frontline): Deploy teardown service + offline 503 (ENG-2922)
| Commit: | 5d9c0c3 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md
| Commit: | 6080894 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): Deploy spend-cap enforcement suspend/resume (ENG-2923)
| Commit: | 855c64e | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): rewire Deploy cancel through ctrl-api (ENG-2922)
| Commit: | b3e8b7c | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl): per-workspace push invocations for deploy billing Replace the journaled-batch push (one big invocation, per-workspace failures recorded as a bool) with a fan-out to DeployBillingPushService: the orchestrator resolves billable workspaces and dispatches one push invocation per workspace, keyed by workspace id. Each push retries and fails in isolation as its own visible invocation and returns a real error. Hourly orchestrator fires-and-forgets; the month-end close awaits the pushes so the closing invoice sees the final total before finalizing.
| Commit: | d6c4011 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | d92216c | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
refactor: move audit to ctrl api
| Commit: | 0fae7c9 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
fix: correlation id and retryable auditlogs
| Commit: | f275272 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
feat(api): add app delete endpoint
| Commit: | 2f333f1 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
refactor: move audit to ctrl api
| Commit: | 685a760 | |
|---|---|---|
| Author: | Andreas Thomas | |
| Committer: | GitHub | |
feat: stop/start and autoscale previews to 0 (#6488) * feat: stop/start and autoscale previews to 0 * clean up * fix: claude hallucinations * fix: address oz comments * merge
| Commit: | 7f655e8 | |
|---|---|---|
| Author: | James | |
fix: Clickhouse user lock down
| Commit: | f80fe50 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md
| Commit: | b48b3a7 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
refactor(ctrl): per-workspace push invocations for deploy billing Replace the journaled-batch push (one big invocation, per-workspace failures recorded as a bool) with a fan-out to DeployBillingPushService: the orchestrator resolves billable workspaces and dispatches one push invocation per workspace, keyed by workspace id. Each push retries and fails in isolation as its own visible invocation and returns a real error. Hourly orchestrator fires-and-forgets; the month-end close awaits the pushes so the closing invoice sees the final total before finalizing.
| Commit: | 4aa093c | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(ctrl): month-end invoice closing webhook for Deploy billing Closes the last correctness gap in the Deploy money path: without this, the billed month-end total was whatever the last hourly push happened to deliver, losing up to an hour of usage at every period roll. New pkg/webhook: a small receiver framework for inbound provider webhooks (method/body policing, signature verification via pluggable verifiers, event-type routing, middleware for integration-specific concerns, and transport metrics so webhook integrations never fly blind): - unkey_webhook_events_total{provider,event,outcome} with outcomes handled / ignored / unhandled / error / verification_failed / bad_request, and unkey_webhook_handler_duration_seconds. Defined in the package itself, next to the code that emits them. - Handlers return nil (200), ErrIgnore (200, counted separately), or an error (500, provider retries) — retry semantics are explicit. - Verifiers live under pkg/webhook/verifiers/ (stripe today; the GitHub webhook can migrate later). Flow: - ctrl-api gains POST /webhooks/stripe (new StripeConfig). On invoice.created for a Deploy workspace renewal invoice it claims the draft (auto_advance off) and dispatches RunDeployBillingClose for the closed period via Restate ingress; the per-customer invoice storm at the roll dedupes onto one durable invocation through the idempotency key. Everything else is ignored and keeps Stripe's own finalization. - RunDeployBillingClose (new CronService handler, keyed by the CLOSED "YYYY-MM" period) pushes every billable workspace's final full-period usage, stamped one second before period end so the "last"-formula meters bill the complete month, then finalizes Deploy workspaces' draft renewal invoices (new internal/invoicecloser), fanned out in bounded batches with one journaled step per workspace. Refuses to close a period that has not ended; losing a finalize race counts as done. - A 01:05 UTC backup cron invokes the same handler with the same idempotency key: if the webhook ran it attaches to that invocation, otherwise drafts are still drafts (auto_advance was disabled) and the sweep closes them. Total ctrl outage degrades to Stripe's one-hour auto-finalization. Prerequisite correctness fix: subscription billing anchors now pin midnight UTC (hour/minute/second 0), not just day_of_month 1. Without it periods are not calendar months and the renewal invoice's meter window would swallow the next month's early month-to-date events, billing the new month's tiny running total instead of the closed month's final one. The hourly push and the close share one pipeline (pushUsage) with an explicit window end and meter-event timestamp; billingperiod gains End(). ENG-2865
| Commit: | 518d0be | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
feat(api): add app delete endpoint
| Commit: | 5538717 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
refactor: move audit to ctrl api
| Commit: | ef6d064 | |
|---|---|---|
| Author: | Oz | |
| Committer: | GitHub | |
feat(api): add project delete (#6476) * feat(api): add project delete * fix: regex * refactor: move audit to ctrl api * refactor: actor usage * refactor: use id instead of slug
| Commit: | 686f9fb | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
feat(api): add app delete endpoint
| Commit: | ecdf259 | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
refactor: move audit to ctrl api
| Commit: | a57b3ca | |
|---|---|---|
| Author: | ogzhanolguncu | |
| Committer: | ogzhanolguncu | |
refactor: move audit to ctrl api
| Commit: | 1f4fbba | |
|---|---|---|
| Author: | Oz | |
| Committer: | GitHub | |
feat(api): add project creation endpoint (#6472) * feat(api): add project creation endpoint * chore: rename query query name was off. it felt like we are querying projects by workspaceSlug and workspaceID * refactor: add projectID to response * refactor: stricter slug * fix: nits * chore: address comments * fix: pullfrog comment * chore: tidy * refactor: allow deleteProtection flag * refactor: call ctrl instead for billing integrations * feat: allow audit in ctrl * chore: fmt * refactor: allow actor util to accept session
| Commit: | 7688166 | |
|---|---|---|
| Author: | Flo | |
| Committer: | Flo | |
feat(billing): Deploy spend-cap detection and budget alerts (ENG-2904) deploy-spend-check cron prices each budgeted workspace's month-to-date Deploy usage locally from ClickHouse, computes net-of-credit overage against the configured budget, and emails the workspace at 50/75/100%. Enforcement (ENG-2923 SUSPEND) is gated on the ENG-2922 teardown primitive and follows. Plan: todo/eng-2904-2923-spend-cap-enforcement.md