-- Council portal restructure — Phase 1
-- Adds: title/cab_joined_date/slug to users; kind+interested status on attendance;
-- pulses, votes, roadmap_items, roadmap_attributions, events, activity tables.

-- ── users: new columns ─────────────────────────────────────────────
ALTER TABLE users ADD COLUMN title           TEXT;
ALTER TABLE users ADD COLUMN cab_joined_date TEXT;
ALTER TABLE users ADD COLUMN slug            TEXT;

-- Partial unique index (allows NULL while enforcing uniqueness on populated slugs)
CREATE UNIQUE INDEX idx_users_slug_unique ON users(slug) WHERE slug IS NOT NULL;

-- Backfill slugs from existing names (seed users have simple ASCII names).
-- New users get slugs generated in db.ts (kebab-case + dedupe).
UPDATE users
   SET slug = LOWER(REPLACE(REPLACE(name, ' ', '-'), '.', ''))
 WHERE slug IS NULL;

-- ── attendance: rebuild for kind + widened status ──────────────────
-- SQLite can't ALTER a CHECK constraint; rebuild is required.
CREATE TABLE attendance_new (
  id            INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id       INTEGER NOT NULL REFERENCES users(id),
  meeting_slug  TEXT    NOT NULL,
  kind          TEXT    NOT NULL DEFAULT 'meeting' CHECK(kind IN ('meeting','event')),
  status        TEXT    NOT NULL CHECK(status IN ('yes','no','interested')),
  updated_at    TEXT    NOT NULL DEFAULT (datetime('now')),
  UNIQUE(user_id, meeting_slug)
);

INSERT INTO attendance_new (id, user_id, meeting_slug, kind, status, updated_at)
SELECT id, user_id, meeting_slug, 'meeting', status, updated_at FROM attendance;

DROP TABLE attendance;
ALTER TABLE attendance_new RENAME TO attendance;

CREATE INDEX idx_attendance_meeting ON attendance(meeting_slug);
CREATE INDEX idx_attendance_kind    ON attendance(kind);

-- ── pulses ─────────────────────────────────────────────────────────
CREATE TABLE pulses (
  id          INTEGER PRIMARY KEY AUTOINCREMENT,
  question    TEXT    NOT NULL,
  context     TEXT,
  options     TEXT    NOT NULL,  -- JSON array of strings (length 2–4)
  opens_at    TEXT    NOT NULL,
  closes_at   TEXT    NOT NULL,
  status      TEXT    NOT NULL DEFAULT 'draft' CHECK(status IN ('draft','open','closed')),
  created_at  TEXT    NOT NULL DEFAULT (datetime('now')),
  created_by  INTEGER NOT NULL REFERENCES users(id)
);
CREATE INDEX idx_pulses_status ON pulses(status);
CREATE INDEX idx_pulses_dates  ON pulses(opens_at, closes_at);

-- ── votes ──────────────────────────────────────────────────────────
CREATE TABLE votes (
  id            INTEGER PRIMARY KEY AUTOINCREMENT,
  pulse_id      INTEGER NOT NULL REFERENCES pulses(id) ON DELETE CASCADE,
  user_id       INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  option_index  INTEGER NOT NULL CHECK(option_index >= 0),
  voted_at      TEXT    NOT NULL DEFAULT (datetime('now')),
  UNIQUE(pulse_id, user_id)
);
CREATE INDEX idx_votes_pulse ON votes(pulse_id);
CREATE INDEX idx_votes_user  ON votes(user_id);

-- ── roadmap_items ──────────────────────────────────────────────────
CREATE TABLE roadmap_items (
  id            INTEGER PRIMARY KEY AUTOINCREMENT,
  title         TEXT    NOT NULL,
  description   TEXT    NOT NULL DEFAULT '',
  status        TEXT    NOT NULL DEFAULT 'exploring' CHECK(status IN ('shipping','beta','exploring')),
  target        TEXT,
  display_order INTEGER NOT NULL DEFAULT 0,
  shipped_at    TEXT,   -- set when status first transitions to 'shipping'; never reset
  created_at    TEXT    NOT NULL DEFAULT (datetime('now')),
  updated_at    TEXT    NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_roadmap_status  ON roadmap_items(status, display_order);
CREATE INDEX idx_roadmap_shipped ON roadmap_items(shipped_at);

-- ── roadmap_attributions ───────────────────────────────────────────
-- Members who shaped this roadmap item. Set explicitly by admin when
-- creating/editing. NOT derived from votes, contributions, or any other signal.
-- Drives the council mark dot-lighting (a quarter lights iff this user has
-- an attribution to an item whose shipped_at falls in that quarter) and the
-- "you shaped this" line on /pulse and /roadmap.
CREATE TABLE roadmap_attributions (
  roadmap_item_id INTEGER NOT NULL REFERENCES roadmap_items(id) ON DELETE CASCADE,
  user_id         INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  created_at      TEXT    NOT NULL DEFAULT (datetime('now')),
  PRIMARY KEY (roadmap_item_id, user_id)
);
CREATE INDEX idx_roadmap_attr_user ON roadmap_attributions(user_id);

-- ── events ─────────────────────────────────────────────────────────
CREATE TABLE events (
  id          INTEGER PRIMARY KEY AUTOINCREMENT,
  slug        TEXT    UNIQUE NOT NULL,
  title       TEXT    NOT NULL,
  kind        TEXT    NOT NULL DEFAULT 'dinner' CHECK(kind IN ('dinner','office_hours','summit','virtual')),
  description TEXT    NOT NULL DEFAULT '',
  location    TEXT    NOT NULL DEFAULT '',
  starts_at   TEXT    NOT NULL,
  ends_at     TEXT,
  capacity    INTEGER,
  photo_url   TEXT,
  created_at  TEXT    NOT NULL DEFAULT (datetime('now')),
  created_by  INTEGER REFERENCES users(id)
);
CREATE INDEX idx_events_starts_at ON events(starts_at);

-- ── activity ───────────────────────────────────────────────────────
-- Drives the live ticker on /pulse. Written automatically by the action
-- it represents (vote cast, RSVP set, roadmap shipped, pulse opened) —
-- never by admin UI. Ticker query: kind != null AND created_at > now - 7d, LIMIT 12.
CREATE TABLE activity (
  id           INTEGER PRIMARY KEY AUTOINCREMENT,
  actor_id     INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  kind         TEXT    NOT NULL CHECK(kind IN ('voted','rsvped','booked_office_hours','roadmap_shipped','pulse_opened')),
  subject_type TEXT    NOT NULL,
  subject_id   INTEGER NOT NULL,
  created_at   TEXT    NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_activity_recent ON activity(created_at);
