Scheduled jobs (migration 00009): cron expressions + @every descriptors,
in-process scheduler (15s scan, missed-run collapse), signed HTTP POST
delivery (X-Primora-Signature), AES-256-GCM sealed secrets returned once,
run history with status/duration/http-code, manual execution, retention
pruning. Viewer reads, admin/developer writes.
Domain events: publishEvent fans document/object/issue/deploy/job
mutations to realtime subscribers and matching webhooks through one
path. Webhook event filter extended to job.run, document.*, object.*.
Realtime: GET /projects/:id/realtime/stream SSE with 25s keepalives and
?token=/?api_key= auth for EventSource clients.
Automation dashboard page: Schedules tab (CRUD, run history, manual run,
secret-once banner) + Live events tab (live badge, pause/clear). Demo
mode parity. primora jobs:* CLI group, six primora_*_job* MCP tools,
AutomationService in the generated client.
Fixes folded in: gzip middleware buffered SSE flushes (broke EventSource
on both streams — */stream now bypasses compression); event payloads
double-marshaled json.RawMessage as base64; compose hardcoded localhost
trusted origins so non-default ports broke sign-in; frontend auth base
URL baked an absolute localhost instead of resolving /auth on origin.
Verified live: stack up on :8085, signed delivery HMAC-checked at sink,
@every 30s schedule firing, run history rendering, document.created
landing in the live events feed.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Remove managed connection seeding: platform-postgres/dragonfly carried
the backend's own DATABASE_URL/DRAGONFLY_URL into tenant projects where
any member could run arbitrary DBX queries against core tables
(Codex P1). NewPlatformService loses the seeds param; firstPartyDBSeeds
deleted.
- Seal db_connections passwords with the existing AES-256-GCM encryptor
(enc:v1:<b64> marker); decrypted only in dbxArgsFor. Legacy plaintext
values still read, but migration 00008 strips them (Codex P1).
- Migration 00008: delete is_managed rows, drop plaintext password keys.
- dbxConnectionName uses the full project UUID — the 8-hex prefix could
collide and alias another project's credentials (Codex P2).
- ci.yml triggers on master, not the nonexistent main/develop branches.
- demo-mode stubs renamed to user-managed connections; CHANGELOG notes
under Unreleased.
Authored By: TDvorak <[email protected]>
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ProjectOverview gains integration_count + webhook_count (enabled only);
dashboard Resources list gets an Integrations row linking to the new
view. Covers the "dashboard widget if cheap" Phase 4 item.
Authored By: TDvorak <[email protected]>
- core.integrations (migration 00005) with AES-256-GCM-encrypted
credentials (PRIMORA_ENCRYPTION_KEY, hex/base64, dev fallback);
has_credentials serialization only — secrets never leave the server
- /projects/:id/integrations list/create/delete/test; health check hits
the stored base URL with a 5s timeout and records status
- Rybbit connector: GET …/integrations/:id/analytics proxies
/api/organizations + /api/sites/* server-side into a normalized shape
- core.webhooks + core.webhook_deliveries; CRUD, deliveries, test, and
POST …/deploy-markers. Events: issue.created (new fingerprint on
ingest), deploy.marker, webhook.test. X-Primora-Signature HMAC-SHA256
over the raw body; in-process dispatcher, 3 attempts, quadratic
backoff, 10s timeout, pending-scan on boot
- HTTPS enforced for public targets; HTTP allowed for loopback/private/
self-hosted sinks
- Integrations page (connectors + webhooks tabs, inline analytics,
delivery log, secret-shown-once), demo-mode stubs
- 12 new primora_* MCP tools
- workspace 0.4.0
Authored By: TDvorak <[email protected]>
Port IMS telemetry into Primora conventions:
- core.components/core.events (migration 00004 + sqlc) scoped to projects
- POST /api/v1/ingest — single or <=500-event batches via project prm_
keys (X-Primora-Key alias), auto-registering components, permissive CORS
- Issues: fingerprint-grouped errors with count/severity/first+last seen
- Reads: events w/ filters + before-cursor, components, stats (1h/24h/7d/30d
bucketed series + component health + totals + metric names), metric
series (avg/p50/p95/max)
- GET .../telemetry/stream — project-scoped SSE through an in-process hub
(buffered subs, drop-on-slow, 25s keepalives); ?api_key=/?token= auth
for EventSource
- Telemetry page: health/issues/events/metrics/integrate tabs, live badge,
390px-clean; demo stubs
- @primora/client SDK (createPrimoraClient: capture*/heartbeat/installAuto,
queued keepalive flushes)
- MCP: primora_list_issues/list_events/telemetry_stats/metric_series
- IMS README deprecation note pointing here
Also fixes workspace pins to 0.3.0 — npm ci in the frontend image was
resolving the unpublished 0.2.0 spec from the registry.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>