-- v1.1.9: queue:receive trigger kind + OutboxSourceKind::Invoke.
--
-- queue:receive is the new trigger kind that fires a script per claimed
-- message. Layout E parent + per-kind detail (mirrors pubsub).
--
-- 'invoke' is added to outbox.source_kind for invoke_async() — a
-- fire-and-forget function-composition call writes an outbox row that
-- the dispatcher fires through the standard executor path.
--
-- Queue itself does NOT need an outbox.source_kind variant (the queue
-- table IS the outbox for queue semantics — see 0034).

ALTER TABLE triggers DROP CONSTRAINT triggers_kind_check;
ALTER TABLE triggers ADD CONSTRAINT triggers_kind_check
    CHECK (kind IN ('kv', 'dead_letter', 'docs', 'cron',
                    'files', 'pubsub', 'email', 'queue'));

ALTER TABLE outbox DROP CONSTRAINT outbox_source_kind_check;
ALTER TABLE outbox ADD CONSTRAINT outbox_source_kind_check
    CHECK (source_kind IN ('http', 'kv', 'dead_letter', 'docs',
                           'cron', 'files', 'pubsub', 'email', 'invoke'));

-- Per-queue-trigger config. Retry policy lives on the parent triggers
-- row (retry_max_attempts, retry_backoff, retry_base_ms) — same
-- pattern as every other trigger kind. visibility_timeout_secs is
-- queue-specific.
--
-- "Exactly one consumer per (app_id, queue_name)" is enforced at the
-- API layer via a pg_advisory_xact_lock on hashtext(app_id || queue_name)
-- + a SELECT-then-INSERT in one transaction (a partial unique index
-- can't reference the parent's app_id column from the detail table).
CREATE TABLE queue_trigger_details (
    trigger_id              UUID PRIMARY KEY REFERENCES triggers(id) ON DELETE CASCADE,
    queue_name              TEXT NOT NULL,
    visibility_timeout_secs INT NOT NULL DEFAULT 30,
    last_fired_at           TIMESTAMPTZ NULL
);

-- Help the dispatcher's "find all active queue consumers" query.
CREATE INDEX idx_queue_trigger_details_queue_name
    ON queue_trigger_details (queue_name);
