mirror of
https://github.com/Dvorinka/Primora.git
synced 2026-10-28 07:41:23 +00:00
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>
89 lines
1.9 KiB
SQL
89 lines
1.9 KiB
SQL
-- name: ListScheduledJobs :many
|
|
SELECT * FROM core.scheduled_jobs
|
|
WHERE project_id = $1
|
|
ORDER BY created_at ASC;
|
|
|
|
-- name: GetScheduledJobByID :one
|
|
SELECT * FROM core.scheduled_jobs
|
|
WHERE id = $1;
|
|
|
|
-- name: CreateScheduledJob :one
|
|
INSERT INTO core.scheduled_jobs (
|
|
project_id,
|
|
name,
|
|
schedule,
|
|
url,
|
|
secret,
|
|
payload,
|
|
enabled,
|
|
next_run_at,
|
|
created_by_user_id
|
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
|
RETURNING *;
|
|
|
|
-- name: UpdateScheduledJob :one
|
|
UPDATE core.scheduled_jobs
|
|
SET name = $3,
|
|
schedule = $4,
|
|
url = $5,
|
|
enabled = $6,
|
|
next_run_at = $7,
|
|
secret = CASE WHEN $8::boolean THEN $9 ELSE secret END,
|
|
payload = CASE WHEN $10::boolean THEN $11 ELSE payload END,
|
|
updated_at = NOW()
|
|
WHERE id = $1
|
|
AND project_id = $2
|
|
RETURNING *;
|
|
|
|
-- name: DeleteScheduledJob :one
|
|
DELETE FROM core.scheduled_jobs
|
|
WHERE id = $1
|
|
AND project_id = $2
|
|
RETURNING id;
|
|
|
|
-- name: ListDueScheduledJobs :many
|
|
SELECT * FROM core.scheduled_jobs
|
|
WHERE enabled
|
|
AND next_run_at IS NOT NULL
|
|
AND next_run_at <= $1;
|
|
|
|
-- name: MarkScheduledJobRan :one
|
|
UPDATE core.scheduled_jobs
|
|
SET last_run_at = $2,
|
|
last_status = $3,
|
|
next_run_at = $4,
|
|
updated_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: InsertScheduledJobRun :one
|
|
INSERT INTO core.scheduled_job_runs (job_id, triggered_by)
|
|
VALUES ($1, $2)
|
|
RETURNING *;
|
|
|
|
-- name: FinishScheduledJobRun :one
|
|
UPDATE core.scheduled_job_runs
|
|
SET status = $2,
|
|
status_code = $3,
|
|
error = $4,
|
|
duration_ms = $5,
|
|
finished_at = NOW()
|
|
WHERE id = $1
|
|
RETURNING *;
|
|
|
|
-- name: ListScheduledJobRuns :many
|
|
SELECT * FROM core.scheduled_job_runs
|
|
WHERE job_id = $1
|
|
ORDER BY created_at DESC
|
|
LIMIT $2;
|
|
|
|
-- name: PruneScheduledJobRuns :exec
|
|
DELETE FROM core.scheduled_job_runs r
|
|
WHERE r.job_id = $1
|
|
AND r.id NOT IN (
|
|
SELECT k.id FROM core.scheduled_job_runs k
|
|
WHERE k.job_id = $1
|
|
ORDER BY k.created_at DESC
|
|
LIMIT $2
|
|
);
|