-- ---------------------------------------------------------------------------
-- Initial schema for CDP Analytics (data-layer).
--
-- Tables owned by this service. Read-only access to ingestion-owned tables
-- (workspaces, profiles, sources, destinations, schema_fields) is assumed.
-- ---------------------------------------------------------------------------

CREATE EXTENSION IF NOT EXISTS "pgcrypto";

-- ---------------------------------------------------------------------------
-- trait_definitions -- declarative computed-trait specs maintained per workspace.
-- ---------------------------------------------------------------------------
CREATE TABLE trait_definitions (
    id            UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    workspace_id  UUID NOT NULL,
    key           TEXT NOT NULL,            -- column name on profile_traits
    name          TEXT NOT NULL,
    description   TEXT,
    -- spec drives how the worker computes the trait (e.g. aggregation over
    -- ClickHouse events). Format is open during prototyping.
    spec          JSONB NOT NULL,
    refresh_every INTERVAL NOT NULL DEFAULT '1 hour',
    enabled       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (workspace_id, key)
);

CREATE INDEX idx_trait_definitions_workspace ON trait_definitions (workspace_id) WHERE enabled;

-- ---------------------------------------------------------------------------
-- profile_traits -- computed values per profile, refreshed by the worker.
-- ---------------------------------------------------------------------------
CREATE TABLE profile_traits (
    workspace_id UUID NOT NULL,
    profile_id   UUID NOT NULL,
    trait_key    TEXT NOT NULL,
    trait_value  JSONB NOT NULL,
    computed_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (workspace_id, profile_id, trait_key)
);

CREATE INDEX idx_profile_traits_workspace_key ON profile_traits (workspace_id, trait_key);

-- ---------------------------------------------------------------------------
-- segment_definitions -- audience segment specs.
-- ---------------------------------------------------------------------------
CREATE TABLE segment_definitions (
    id            UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    workspace_id  UUID NOT NULL,
    slug          TEXT NOT NULL,
    name          TEXT NOT NULL,
    description   TEXT,
    -- spec is the filter tree evaluated against profiles + events + traits.
    spec          JSONB NOT NULL,
    refresh_every INTERVAL NOT NULL DEFAULT '1 hour',
    enabled       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    last_refreshed_at TIMESTAMPTZ,
    UNIQUE (workspace_id, slug)
);

CREATE INDEX idx_segment_definitions_workspace ON segment_definitions (workspace_id) WHERE enabled;

-- ---------------------------------------------------------------------------
-- segment_memberships -- history table powering delta Reverse ETL.
-- exited_at NULL means the profile is currently a member.
-- ---------------------------------------------------------------------------
CREATE TABLE segment_memberships (
    segment_id   UUID NOT NULL REFERENCES segment_definitions (id) ON DELETE CASCADE,
    profile_id   UUID NOT NULL,
    entered_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
    exited_at    TIMESTAMPTZ
);

CREATE INDEX idx_segment_memberships_active ON segment_memberships (segment_id, profile_id) WHERE exited_at IS NULL;
CREATE INDEX idx_segment_memberships_profile ON segment_memberships (profile_id);

-- ---------------------------------------------------------------------------
-- saved_queries -- user-saved query specs from the Explore / SQL UI.
-- ---------------------------------------------------------------------------
CREATE TABLE saved_queries (
    id           UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    workspace_id UUID NOT NULL,
    owner_id     UUID,
    name         TEXT NOT NULL,
    kind         TEXT NOT NULL
                 CHECK (kind IN ('events', 'sql', 'funnel', 'retention', 'session')),
    spec         JSONB NOT NULL,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_saved_queries_workspace ON saved_queries (workspace_id, kind);
