feat: webhook notifications for media processing events#18
Merged
Conversation
release: v1.0.0 — initial LTS
release: promote README + docs to master
- Add owner_id to assets table (migration 000004) - Add user_id + events columns to webhook_registrations (migration 000005) - Webhook CRUD API: POST/GET/DELETE /api/v1/webhooks (per-tenant) - Worker inserts webhook_deliveries on job.started, job.done, job.failed - Go API inserts job.starting deliveries in the upload transaction - Webhook dispatcher: polls pending deliveries, HMAC-SHA256 signs, delivers with exponential backoff + jitter (5 attempts, 5min cap) - Cleanup goroutine for delivered rows (7-day retention) - OTel metrics: webhook.delivery.total, duration, failures, pending gauge - Config: WEBHOOK_POLL_INTERVAL, BATCH_SIZE, TIMEOUT, MAX_ATTEMPTS, RETENTION - Unit tests (Go + Python) and integration test with httptest - Dev-test overlay: docker-compose.webhooks.yml + scripts/test-webhooks.sh
Make MPiper demo-ready so a host-run client can exercise the full
pipeline (presign -> upload -> complete -> worker -> variants -> webhooks)
exactly like a real client, for both image and video.
Storage:
- storagex: add PublicEndpoint to Config; S3 impl presigns and builds
public URLs against the public endpoint while server-side object I/O
stays on the internal endpoint (SigV4 signs Host, so presign must
target the host the client connects to). Back-compat: falls back to
the internal endpoint when public is unset.
- config: read S3_PUBLIC_ENDPOINT_URL; pass through asset service.
- worker: BucketConfig.public_endpoint_url + S3Storage.public_url use
the public endpoint for persisted variant URLs; I/O stays internal.
- docker-compose: set S3_ENDPOINT_URL (minio:9000) +
S3_PUBLIC_ENDPOINT_URL (localhost:9000) for api and worker.
Health check:
- implement cmd/server --health-check as a lightweight /healthz probe
instead of a second server boot (which failed to bind the port and
left the api container permanently unhealthy, blocking the worker).
Demo + docs:
- scripts/demo-e2e.sh: host-run end-to-end driver covering image+video
and the job.starting/started/done webhook lifecycle, with a PASS/FAIL
summary; tests/test_assets/sample.mp4 fixture.
- README/CLAUDE: correct port (5010) and endpoints (storage/presign,
assets/{id}/complete), document auth + the split endpoint, add
webhooks and run-the-demo sections, refresh roadmap.
Tests:
- storagex: cover split-endpoint presign + PublicURL (and back-compat).
- worker: add S3 public-endpoint tests; fix stale image-pipeline test.
Also bundles the in-progress webhook/outbox feature work on this branch
(outbox relay + repo + migration, worker processing/config updates,
worker Dockerfile, deps).
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.
Summary
Adds a complete webhook notification system that notifies users when their media processing jobs transition through lifecycle states — and makes the whole pipeline demo-ready by letting a host-run client drive presign → upload → complete → worker → variants → webhooks exactly like a real client, for both image and video.
Changes
Webhooks
Events:
job.starting,job.started,job.done,job.failedArchitecture:
webhook_deliveriesrows atomically with job status transitionsassets.owner_id→webhook_registrations.user_idNew endpoints:
POST /api/v1/webhooks— register a webhookGET /api/v1/webhooks— list user's webhooksDELETE /api/v1/webhooks/{id}— delete a webhookMigrations:
owner_idto assetsuser_id+eventsto webhook_registrationsObservability: OTel metrics for delivery count, duration, failures, and pending gauge.
Split storage endpoint (internal vs public)
Presigned upload URLs were signed against the compose-internal host
minio:9000, which a host client cannot resolve — and SigV4 signs theHostheader, so the URL can't be rewritten afterwards. Storage now supports two endpoints:S3_ENDPOINT_URL— internal/server-side endpoint for object I/O (http://minio:9000)S3_PUBLIC_ENDPOINT_URL— client-facing endpoint baked into presigned + persisted variant URLs (http://localhost:9000)Go
storagex: separate presign client bound to the public endpoint;PublicURLprefers it. Back-compat — falls back to the internal endpoint when public is unset.Worker
S3Storage:public_url()uses the public endpoint; object I/O stays internal.docker-compose.yml: both endpoints wired forapiandworker.Health check fix
cmd/server --health-checkwas unimplemented — it booted a second server that failed to bind port 5010, leaving theapicontainer permanentlyunhealthyand blocking theworker(whichdepends_on api: service_healthy). It is now a lightweight/healthzprobe.Demo + docs
scripts/demo-e2e.sh— host-run end-to-end driver for image and video, including thejob.starting → job.started → job.donewebhook lifecycle, with a PASS/FAIL summary and non-zero exit on failure. Addstests/test_assets/sample.mp4.5010) and endpoints (/api/v1/storage/presign,GET /api/v1/assets/{id}/complete), documented auth + the split endpoint, added webhooks and run-the-demo sections, refreshed roadmap.Testing
scripts/demo-e2e.sh→ 23/23 checks pass (image 3 webp variants; video poster + 720p + preview; all variants fetchable from host overlocalhost:9000; all webhooks delivered)How to test