-- Migration 099: Flexoptix Internal Demand Data Schema
-- ⚠️  SECURITY: This table contains proprietary Flexoptix business intelligence.
--     Raw records MUST NEVER be exposed via any public-facing API endpoint.
--     Use ONLY for aggregated forecasting and hype cycle calibration.
--     Data source: internal XLSX export (AES-256-CBC encrypted at rest on local infra)
--
-- velocity_class breakdown:
--   fast_mover  — demand_12m >= 100 units/month
--   regular     — demand_12m >= 10 and < 100
--   slow_mover  — demand_12m > 0 and < 10
--   dead_stock  — demand_12m = 0

CREATE TABLE IF NOT EXISTS flexoptix_internal_demand (
  id               UUID        NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  sku              TEXT        NOT NULL,                   -- Artikel-Nr (e.g. AT.L.1BU)
  description      TEXT,                                   -- Kurzbeschreibung
  transceiver_id   UUID        REFERENCES transceivers(id) ON DELETE SET NULL,
  demand_12m       NUMERIC(12,2) NOT NULL DEFAULT 0,       -- Bedarf/Monat letzte 12 Monate
  demand_3m        NUMERIC(12,2) NOT NULL DEFAULT 0,       -- Bedarf/Monat letzte 3 Monate
  demand_trend_pct NUMERIC(8,2),                           -- (3m-12m)/12m*100  (+= accelerating)
  velocity_class   TEXT        CHECK (velocity_class IN ('fast_mover','regular','slow_mover','dead_stock')),
  imported_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  data_source      TEXT        NOT NULL DEFAULT 'flexoptix_internal',
  is_internal      BOOLEAN     NOT NULL DEFAULT TRUE,      -- security guard — always TRUE

  CONSTRAINT flexoptix_demand_sku_unique UNIQUE (sku)
);

COMMENT ON TABLE flexoptix_internal_demand IS
  'INTERNAL — Flexoptix proprietary sales velocity data. Never expose raw rows publicly.';

-- Indexes
CREATE INDEX IF NOT EXISTS idx_foxd_sku        ON flexoptix_internal_demand (sku);
CREATE INDEX IF NOT EXISTS idx_foxd_transceiver ON flexoptix_internal_demand (transceiver_id)
  WHERE transceiver_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_foxd_velocity    ON flexoptix_internal_demand (velocity_class);
CREATE INDEX IF NOT EXISTS idx_foxd_demand_12m  ON flexoptix_internal_demand (demand_12m DESC);
CREATE INDEX IF NOT EXISTS idx_foxd_is_internal ON flexoptix_internal_demand (is_internal);

-- Row-level security: prevent accidental exposure
-- (API layer enforces localhost-only on top of this)
ALTER TABLE flexoptix_internal_demand ENABLE ROW LEVEL SECURITY;

-- Only the tip user (application) can read — no PUBLIC access
CREATE POLICY foxd_tip_read ON flexoptix_internal_demand
  FOR SELECT TO tip USING (is_internal = TRUE);

CREATE POLICY foxd_tip_write ON flexoptix_internal_demand
  FOR ALL TO tip USING (TRUE) WITH CHECK (is_internal = TRUE);

-- Aggregated demand view: technology-level rollup (safe to expose — no individual SKUs)
CREATE OR REPLACE VIEW v_demand_by_speed AS
  SELECT
    t.speed_gbps,
    t.form_factor,
    COUNT(DISTINCT d.sku)                          AS sku_count,
    SUM(d.demand_12m)                              AS total_demand_12m,
    SUM(d.demand_3m)                               AS total_demand_3m,
    ROUND(AVG(d.demand_12m), 2)                    AS avg_demand_12m,
    ROUND(AVG(d.demand_trend_pct), 1)              AS avg_trend_pct,
    COUNT(*) FILTER (WHERE d.velocity_class = 'fast_mover')   AS fast_movers,
    COUNT(*) FILTER (WHERE d.velocity_class = 'regular')       AS regular,
    COUNT(*) FILTER (WHERE d.velocity_class = 'slow_mover')    AS slow_movers,
    COUNT(*) FILTER (WHERE d.velocity_class = 'dead_stock')    AS dead_stock
  FROM flexoptix_internal_demand d
  JOIN transceivers t ON t.id = d.transceiver_id
  GROUP BY t.speed_gbps, t.form_factor
  ORDER BY total_demand_12m DESC;

COMMENT ON VIEW v_demand_by_speed IS
  'Aggregated demand rollup by technology — safe for API exposure (no individual SKUs).';
