-- Phase 5 / M4b (v1.2 Hierarchies): TRIGGER templates (§4.5).
--
-- The trigger half of templates (M4a shipped routes). A `[group]` manifest
-- declares `[[trigger_templates.<kind>]]`; the apply fans each one out into a
-- concrete per-`app_id` trigger on every descendant app, reusing the same
-- expansion engine, placeholder set (`{app_slug}`/`{env}`/`{var:NAME}`), and
-- `from_template` provenance as routes.
--
-- A trigger's parameters vary by kind (collection_glob/ops, schedule/timezone,
-- topic_pattern, queue_name, inbound_secret_ref, …), so the template stores the
-- whole `BundleTrigger` wire object as `spec` JSONB (kind tag included). The
-- expansion resolves placeholders in the spec's string leaves, then rebuilds the
-- typed trigger and inserts it through the normal trigger path (email secrets
-- are resolved + re-sealed per app, exactly like a hand-declared email trigger).

CREATE TABLE trigger_templates (
    id         UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    group_id   UUID NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
    -- Identity/upsert key, unique per group (case-insensitive).
    name       TEXT NOT NULL,
    -- The full `BundleTrigger` wire object (internally tagged by `kind`), with
    -- placeholders left unresolved. Rebuilt + resolved per descendant at apply.
    spec       JSONB NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX trigger_templates_group_name_idx
    ON trigger_templates (group_id, LOWER(name));

-- Provenance on expanded triggers (mirrors routes.from_template, 0053). NULL =
-- hand-declared; non-NULL = stamped from this template, managed by expansion.
ALTER TABLE triggers ADD COLUMN from_template UUID;
CREATE INDEX triggers_from_template_idx ON triggers (app_id, from_template);
