Chatverlauf (LotseConversation/-Message) und Aktionskarten (LotseActionProposal) als Mandantentabellen mit RLS; Schalter lotseChatEnabled. Tool-Use-Schleife mit Runden- und Tokengrenze, Datenminimierung per Platzhalter, Auftragszuordnung im Sichtbarkeits-Scope, Bestätigen/Verwerfen/Alle bestätigen mit Hash, Ablauf und Idempotenz, Transkriptions-API. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
89 lines
3.2 KiB
SQL
89 lines
3.2 KiB
SQL
-- L16 Lotse-Chat für Monteure: Chatverlauf, Aktionsvorschläge, Schalter je Mandant
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "LotseMessageRole" AS ENUM ('user', 'assistant', 'tool');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "LotseProposalStatus" AS ENUM ('proposed', 'confirmed', 'discarded', 'expired', 'failed');
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "tenant_settings" ADD COLUMN "lotse_chat_enabled" BOOLEAN NOT NULL DEFAULT true;
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "lotse_conversations" (
|
|
"id" TEXT NOT NULL,
|
|
"tenant_id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"work_order_id" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
"last_message_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "lotse_conversations_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "lotse_messages" (
|
|
"id" TEXT NOT NULL,
|
|
"tenant_id" TEXT NOT NULL,
|
|
"conversation_id" TEXT NOT NULL,
|
|
"role" "LotseMessageRole" NOT NULL,
|
|
"text" TEXT NOT NULL,
|
|
"content" JSONB,
|
|
"ai_generation_id" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "lotse_messages_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "lotse_action_proposals" (
|
|
"id" TEXT NOT NULL,
|
|
"tenant_id" TEXT NOT NULL,
|
|
"conversation_id" TEXT NOT NULL,
|
|
"message_id" TEXT,
|
|
"user_id" TEXT NOT NULL,
|
|
"work_order_id" TEXT,
|
|
"kind" TEXT NOT NULL,
|
|
"payload" JSONB NOT NULL,
|
|
"payload_hash" TEXT NOT NULL,
|
|
"status" "LotseProposalStatus" NOT NULL DEFAULT 'proposed',
|
|
"expires_at" TIMESTAMP(3) NOT NULL,
|
|
"result" JSONB,
|
|
"error_code" TEXT,
|
|
"confirmed_at" TIMESTAMP(3),
|
|
"confirmed_by_id" TEXT,
|
|
"decided_at" TIMESTAMP(3),
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "lotse_action_proposals_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "lotse_conversations_tenant_id_user_id_last_message_at_idx" ON "lotse_conversations"("tenant_id", "user_id", "last_message_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "lotse_conversations_tenant_id_last_message_at_idx" ON "lotse_conversations"("tenant_id", "last_message_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "lotse_messages_tenant_id_conversation_id_created_at_idx" ON "lotse_messages"("tenant_id", "conversation_id", "created_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "lotse_action_proposals_tenant_id_conversation_id_created_at_idx" ON "lotse_action_proposals"("tenant_id", "conversation_id", "created_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "lotse_action_proposals_tenant_id_user_id_status_idx" ON "lotse_action_proposals"("tenant_id", "user_id", "status");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "lotse_messages" ADD CONSTRAINT "lotse_messages_conversation_id_fkey" FOREIGN KEY ("conversation_id") REFERENCES "lotse_conversations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "lotse_action_proposals" ADD CONSTRAINT "lotse_action_proposals_conversation_id_fkey" FOREIGN KEY ("conversation_id") REFERENCES "lotse_conversations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
|
|
-- L16: Mandantentrennung (RLS) für die neuen Tabellen
|
|
SELECT enable_tenant_rls('lotse_conversations');
|
|
SELECT enable_tenant_rls('lotse_messages');
|
|
SELECT enable_tenant_rls('lotse_action_proposals');
|