managarten/services/mana-auth/sql/005_personas.sql
Till JS 52f53c844b chore(mana-auth): add 005 persona tables migration
Documents the SQL that was applied manually to match the personas.ts
Drizzle schema introduced in 493db0c3b. Idempotent. See
docs/plans/mana-mcp-and-personas.md for the design. Required because
the spaces tables created alongside personas sit outside the auth
schemaFilter, and pre-existing public enums would otherwise trip
drizzle-kit push (resolved separately in migration 006).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:36:26 +02:00

77 lines
3.5 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Migration 005: Personas
--
-- Adds the three `auth.personas*` tables introduced by the M2.ac MCP
-- work (feat commit 493db0c3b). See docs/plans/mana-mcp-and-personas.md
-- for the full spec, and src/db/schema/personas.ts for the Drizzle
-- definitions.
--
-- A `persona` is an auto-driven user (archetype + system prompt + module
-- mix) that goes through the normal auth/register/JWT pipeline — kept in
-- the auth schema so foreign keys to `auth.users` stay straightforward.
-- The companion tables are append-only:
-- - persona_actions: every MCP tool call the runner makes
-- - persona_feedback: module-scoped quality ratings emitted per tick
--
-- This SQL matches what drizzle-kit push would emit for personas.ts. We
-- apply it manually because the other tables created alongside personas
-- (spaces.credentials, spaces.module_permissions) live outside the auth
-- schemaFilter and pre-existing public enums would otherwise trip the
-- push. See migration 006 for the follow-up that makes push clean.
--
-- Idempotent: re-running on a partially-migrated DB is safe.
-- ─── personas ───────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS auth.personas (
user_id TEXT PRIMARY KEY NOT NULL,
archetype TEXT NOT NULL,
system_prompt TEXT NOT NULL,
module_mix JSONB NOT NULL,
tick_cadence TEXT NOT NULL DEFAULT 'daily',
last_active_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT personas_user_id_users_id_fk
FOREIGN KEY (user_id) REFERENCES auth.users (id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS personas_archetype_idx
ON auth.personas (archetype);
-- ─── persona_actions ────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS auth.persona_actions (
id TEXT PRIMARY KEY NOT NULL,
persona_id TEXT NOT NULL,
tick_id TEXT NOT NULL,
tool_name TEXT NOT NULL,
input_hash TEXT,
result TEXT NOT NULL,
error_message TEXT,
latency_ms INTEGER,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT persona_actions_persona_id_personas_user_id_fk
FOREIGN KEY (persona_id) REFERENCES auth.personas (user_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS persona_actions_persona_idx
ON auth.persona_actions (persona_id, created_at);
CREATE INDEX IF NOT EXISTS persona_actions_tick_idx
ON auth.persona_actions (tick_id);
-- ─── persona_feedback ───────────────────────────────────────────
CREATE TABLE IF NOT EXISTS auth.persona_feedback (
id TEXT PRIMARY KEY NOT NULL,
persona_id TEXT NOT NULL,
tick_id TEXT NOT NULL,
module TEXT NOT NULL,
rating SMALLINT NOT NULL,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT persona_feedback_persona_id_personas_user_id_fk
FOREIGN KEY (persona_id) REFERENCES auth.personas (user_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS persona_feedback_persona_idx
ON auth.persona_feedback (persona_id, created_at);
CREATE INDEX IF NOT EXISTS persona_feedback_module_idx
ON auth.persona_feedback (module, created_at);