-- dd0c/cost V1 schema

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Tenants
CREATE TABLE tenants (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL,
    slug TEXT NOT NULL UNIQUE,
    tier TEXT NOT NULL DEFAULT 'free' CHECK (tier IN ('free', 'pro')),
    governance_mode TEXT NOT NULL DEFAULT 'shadow' CHECK (governance_mode IN ('shadow', 'audit', 'enforce')),
    governance_started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    stripe_customer_id TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- AWS accounts linked to tenants
CREATE TABLE aws_accounts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    account_id TEXT NOT NULL,
    account_name TEXT,
    role_arn TEXT NOT NULL,
    regions TEXT[] NOT NULL DEFAULT '{us-east-1}',
    enabled BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE(tenant_id, account_id)
);

-- Cost baselines (Welford running stats)
CREATE TABLE baselines (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    account_id TEXT NOT NULL,
    resource_type TEXT NOT NULL,
    welford_count INT NOT NULL DEFAULT 0,
    welford_mean NUMERIC(12,6) NOT NULL DEFAULT 0,
    welford_m2 NUMERIC(20,6) NOT NULL DEFAULT 0,
    version INT NOT NULL DEFAULT 1,  -- Optimistic locking for concurrent updates
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE(tenant_id, account_id, resource_type)
);

-- Anomaly events
CREATE TABLE anomalies (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    account_id TEXT NOT NULL,
    resource_type TEXT NOT NULL,
    region TEXT NOT NULL,
    hourly_cost NUMERIC(10,4) NOT NULL,
    score NUMERIC(5,2) NOT NULL,
    baseline_mean NUMERIC(12,6) NOT NULL,
    baseline_stddev NUMERIC(12,6) NOT NULL,
    status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'acknowledged', 'snoozed', 'expected', 'resolved')),
    snoozed_until TIMESTAMPTZ,
    tags JSONB NOT NULL DEFAULT '{}',
    detected_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_anomalies_tenant ON anomalies(tenant_id, status, detected_at DESC);

-- Remediation actions
CREATE TABLE remediation_actions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    anomaly_id UUID NOT NULL REFERENCES anomalies(id) ON DELETE CASCADE,
    action_type TEXT NOT NULL CHECK (action_type IN ('stop_instance', 'resize', 'snooze', 'mark_expected')),
    status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'executing', 'completed', 'failed')),
    requested_by TEXT NOT NULL,  -- Slack user ID
    requested_by_role TEXT NOT NULL DEFAULT 'viewer',
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    completed_at TIMESTAMPTZ
);

-- Notification configs
CREATE TABLE notification_configs (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    channel TEXT NOT NULL CHECK (channel IN ('slack', 'email')),
    config JSONB NOT NULL DEFAULT '{}',
    min_score NUMERIC(5,2) NOT NULL DEFAULT 50,
    enabled BOOLEAN NOT NULL DEFAULT true,
    UNIQUE(tenant_id, channel)
);

-- RLS
ALTER TABLE baselines ENABLE ROW LEVEL SECURITY;
ALTER TABLE anomalies ENABLE ROW LEVEL SECURITY;
ALTER TABLE remediation_actions ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_iso_baselines ON baselines
    USING (tenant_id::text = current_setting('app.tenant_id', true));
CREATE POLICY tenant_iso_anomalies ON anomalies
    USING (tenant_id::text = current_setting('app.tenant_id', true));
CREATE POLICY tenant_iso_remediation ON remediation_actions
    USING (tenant_id::text = current_setting('app.tenant_id', true));
