Changeset 0.23.1 (#154)
This commit is contained in:
@@ -17,6 +17,14 @@ import (
|
||||
// DB is the application-wide database connection pool.
|
||||
var DB *sql.DB
|
||||
|
||||
// rawDSN holds the Postgres connection string for LISTEN/NOTIFY consumers.
|
||||
// Empty when running SQLite.
|
||||
var rawDSN string
|
||||
|
||||
// DSN returns the raw Postgres connection string, or "" for SQLite.
|
||||
// Used by the event broadcast layer to open a dedicated listener connection.
|
||||
func DSN() string { return rawDSN }
|
||||
|
||||
// Connect opens a connection pool to the configured database.
|
||||
// Driver is selected by DB_DRIVER env var: "postgres" (default) or "sqlite".
|
||||
// For SQLite the DATABASE_URL is treated as a file path; ":memory:" is supported.
|
||||
@@ -45,6 +53,7 @@ func connectPostgres(dsn string) error {
|
||||
|
||||
// Log the database name for operational clarity (never log credentials).
|
||||
dbName = extractDBName(dsn)
|
||||
rawDSN = dsn
|
||||
log.Printf("Connecting to Postgres database %q ...", dbName)
|
||||
|
||||
var err error
|
||||
|
||||
46
server/database/migrations/016_v023_multiuser.sql
Normal file
46
server/database/migrations/016_v023_multiuser.sql
Normal file
@@ -0,0 +1,46 @@
|
||||
-- ==========================================
|
||||
-- Chat Switchboard — 006 Multi-User: DMs + Channels
|
||||
-- ==========================================
|
||||
-- Extends channels with 'dm' and 'channel' types, ai_mode, and topic.
|
||||
-- Adds presence tracking table.
|
||||
-- ICD §3 (Channels & Conversations) — v0.23.1
|
||||
-- ==========================================
|
||||
|
||||
-- ── Channel type extension ───────────────────────────────────────────
|
||||
-- Add 'dm' (human-to-human, AI silent unless @mentioned)
|
||||
-- Add 'channel' (named persistent space, configurable ai_mode)
|
||||
-- Existing 'direct', 'group', 'workflow' are unchanged.
|
||||
ALTER TABLE channels DROP CONSTRAINT IF EXISTS channels_type_check;
|
||||
ALTER TABLE channels ADD CONSTRAINT channels_type_check
|
||||
CHECK (type IN ('direct', 'dm', 'group', 'channel', 'workflow'));
|
||||
|
||||
-- ── ai_mode ──────────────────────────────────────────────────────────
|
||||
-- auto : AI responds to every message (existing behavior for 'direct')
|
||||
-- mention_only : AI silent unless @mentioned (default for 'dm')
|
||||
-- off : AI disabled entirely
|
||||
ALTER TABLE channels
|
||||
ADD COLUMN IF NOT EXISTS ai_mode VARCHAR(20) NOT NULL DEFAULT 'auto'
|
||||
CHECK (ai_mode IN ('auto', 'mention_only', 'off'));
|
||||
|
||||
-- Back-fill: DM channels should be mention_only
|
||||
-- (No existing rows should have type='dm' yet, but be safe)
|
||||
UPDATE channels SET ai_mode = 'mention_only' WHERE type = 'dm' AND ai_mode = 'auto';
|
||||
|
||||
-- ── topic ─────────────────────────────────────────────────────────────
|
||||
ALTER TABLE channels
|
||||
ADD COLUMN IF NOT EXISTS topic TEXT;
|
||||
|
||||
-- ── Presence (in-memory heartbeat, DB stores last_seen for persistence) ──
|
||||
-- Not queried at high frequency — updated by heartbeat (30s), read on load.
|
||||
CREATE TABLE IF NOT EXISTS user_presence (
|
||||
user_id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||
last_seen TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'online'
|
||||
CHECK (status IN ('online', 'away', 'offline'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_presence_last_seen ON user_presence(last_seen DESC);
|
||||
|
||||
COMMENT ON TABLE user_presence IS 'Heartbeat-driven presence. Rows upserted every 30s by active clients.';
|
||||
COMMENT ON COLUMN channels.ai_mode IS 'auto=respond always, mention_only=@mention required, off=AI disabled';
|
||||
COMMENT ON COLUMN channels.topic IS 'Short channel description shown in header';
|
||||
23
server/database/migrations/sqlite/016_v023_multiuser.sql
Normal file
23
server/database/migrations/sqlite/016_v023_multiuser.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
-- ==========================================
|
||||
-- Chat Switchboard — 006 Multi-User: DMs + Channels (SQLite)
|
||||
-- ==========================================
|
||||
-- SQLite does not support ALTER CONSTRAINT or DROP CONSTRAINT.
|
||||
-- The type check is enforced by application logic for SQLite.
|
||||
-- ==========================================
|
||||
|
||||
-- ── ai_mode ──────────────────────────────────────────────────────────
|
||||
-- SQLite ignores CHECK constraints on existing rows; we add the column
|
||||
-- and rely on app-layer validation for the enum values.
|
||||
ALTER TABLE channels ADD COLUMN ai_mode TEXT NOT NULL DEFAULT 'auto';
|
||||
|
||||
-- ── topic ─────────────────────────────────────────────────────────────
|
||||
ALTER TABLE channels ADD COLUMN topic TEXT;
|
||||
|
||||
-- ── Presence ──────────────────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS user_presence (
|
||||
user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||
last_seen DATETIME NOT NULL DEFAULT (datetime('now')),
|
||||
status TEXT NOT NULL DEFAULT 'online'
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_presence_last_seen ON user_presence(last_seen DESC);
|
||||
Reference in New Issue
Block a user