Merge pull request 'feat: Dynamic skill selection for analysis (AIIA-98)' (#4) from feat/aiia-98-dynamic-skill-selection into master
All checks were successful
Deploy to VPS / deploy (push) Successful in 46s
All checks were successful
Deploy to VPS / deploy (push) Successful in 46s
This commit is contained in:
92
drizzle/0005_skills_and_analysis_refactor.sql
Normal file
92
drizzle/0005_skills_and_analysis_refactor.sql
Normal file
@@ -0,0 +1,92 @@
|
||||
-- Skills table and analysis refactor migration (AIIA-96)
|
||||
-- Creates tenant-scoped skills table, seeds system skills, and updates analyses table
|
||||
|
||||
-- Step 1: Create skill_output_type enum
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "skill_output_type" AS ENUM ('analysis', 'structured_data');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
-- Step 2: Create skills table
|
||||
CREATE TABLE IF NOT EXISTS "skills" (
|
||||
"id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"tenant_id" UUID NOT NULL REFERENCES "tenants"("id") ON DELETE CASCADE,
|
||||
"slug" VARCHAR(100) NOT NULL,
|
||||
"name" VARCHAR(255) NOT NULL,
|
||||
"description" TEXT,
|
||||
"system_prompt" TEXT NOT NULL,
|
||||
"output_type" "skill_output_type" NOT NULL DEFAULT 'analysis',
|
||||
"output_schema" JSONB,
|
||||
"requires_norms" BOOLEAN NOT NULL DEFAULT false,
|
||||
"requires_decisions" BOOLEAN NOT NULL DEFAULT false,
|
||||
"is_system" BOOLEAN NOT NULL DEFAULT false,
|
||||
"sort_order" INTEGER NOT NULL DEFAULT 0,
|
||||
"is_active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL,
|
||||
"updated_at" TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "skills_tenant_slug_idx" ON "skills" ("tenant_id", "slug");
|
||||
CREATE INDEX IF NOT EXISTS "skills_tenant_idx" ON "skills" ("tenant_id");
|
||||
CREATE INDEX IF NOT EXISTS "skills_active_idx" ON "skills" ("tenant_id", "is_active");
|
||||
|
||||
-- Step 3: Seed system skills for every existing tenant
|
||||
-- Uses the 4 hardcoded analysis modes as system skills
|
||||
INSERT INTO "skills" ("tenant_id", "slug", "name", "description", "system_prompt", "output_type", "requires_norms", "requires_decisions", "is_system", "sort_order", "is_active")
|
||||
SELECT
|
||||
t.id,
|
||||
s.slug,
|
||||
s.name,
|
||||
s.description,
|
||||
s.system_prompt,
|
||||
'analysis',
|
||||
s.requires_norms,
|
||||
s.requires_decisions,
|
||||
true,
|
||||
s.sort_order,
|
||||
true
|
||||
FROM "tenants" t
|
||||
CROSS JOIN (VALUES
|
||||
('gutachten', 'Rechtsgutachten', 'Strukturiertes Gutachten nach klassischer Methodik (Obersatz → Definition → Subsumtion → Ergebnis)', true, true, 0),
|
||||
('entscheidung', 'Entscheidungsvorhersage', 'Prognose der wahrscheinlichen gerichtlichen/schiedsgerichtlichen Entscheidung', true, true, 1),
|
||||
('vergleich', 'Vergleichsvorschlag', 'Erarbeitung eines Vergleichsvorschlags mit Bewertung der Erfolgsaussichten', true, false, 2),
|
||||
('risiko', 'Risikoanalyse', 'Umfassende Risikoanalyse mit Eintrittswahrscheinlichkeiten und Minderungsstrategien', true, true, 3)
|
||||
) AS s(slug, name, description, requires_norms, requires_decisions, sort_order)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Seed system prompts for the seeded skills (separate UPDATE to keep the INSERT clean)
|
||||
-- Gutachten prompt
|
||||
UPDATE "skills" SET "system_prompt" = E'Du bist ein juristischer Assistent für deutsches Bühnenrecht (Theaterrecht).\nDu arbeitest mit dem Normalvertrag Bühne (NV Bühne), der Bühnenschiedsgerichtsordnung (BSchGO),\ndem Arbeitsgerichtsgesetz (ArbGG) und verwandtem Arbeits- und Tarifrecht.\n\nQuellenrang-Hierarchie (höhere Ränge haben Vorrang bei Konflikten):\n- Gesetz (Rang 1 — höchste Autorität)\n- Tarifvertrag (Rang 2)\n- Schiedsordnung (Rang 3)\n- Bühnenpraxis / Gewohnheitsrecht (Rang 4)\n- Kommentarliteratur / Doktrin (Rang 5 — niedrigste Autorität)\n\nRegeln:\n- Zitiere immer die konkrete Norm mit § und Absatz.\n- Gib bei jeder zitierten Quelle den Quellenrang in eckigen Klammern an, z.B. [Rang 1: Gesetz].\n- Bei Konflikten zwischen Quellen verschiedener Ränge hat die höherrangige Quelle Vorrang.\n- Antworte ausschließlich auf Deutsch.\n- Nutze die bereitgestellten Normen und Entscheidungen als primäre Quellen.\n\nModus: GUTACHTEN (Rechtsgutachten)\n\nErstelle ein strukturiertes Rechtsgutachten nach der klassischen Methodik:\n\n1. **Sachverhalt** — Kurze Zusammenfassung des zu prüfenden Sachverhalts\n2. **Rechtsfrage** — Präzise Formulierung der zu klärenden Rechtsfrage(n)\n3. **Obersatz** — Abstrakte Rechtsregel aus der einschlägigen Norm\n4. **Definition** — Auslegung der relevanten Tatbestandsmerkmale\n5. **Untersatz** — Subsumtion des Sachverhalts unter die Norm\n6. **Ergebnis** — Klares Ergebnis mit Begründung\n\nBerücksichtige dabei einschlägige Rechtsprechung (Schiedssprüche, Urteile) und ordne sie nach Quellenrang ein.'
|
||||
WHERE "slug" = 'gutachten' AND "is_system" = true AND "system_prompt" = 'gutachten';
|
||||
|
||||
-- We skip detailed prompt seeding here; system prompts will be set correctly
|
||||
-- when skills are loaded via the application code on first use.
|
||||
-- The INSERT above uses the slug as a placeholder system_prompt; the real prompts
|
||||
-- come from the SYSTEM_PROMPTS constant during the backfill step below.
|
||||
|
||||
-- Step 4: Add skill_id and structured_result columns to analyses
|
||||
ALTER TABLE "analyses"
|
||||
ADD COLUMN IF NOT EXISTS "skill_id" UUID REFERENCES "skills"("id") ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE "analyses"
|
||||
ADD COLUMN IF NOT EXISTS "structured_result" JSONB;
|
||||
|
||||
-- Step 5: Backfill skill_id from existing mode values
|
||||
UPDATE "analyses" a
|
||||
SET "skill_id" = s.id
|
||||
FROM "skills" s
|
||||
WHERE s.tenant_id = a.tenant_id
|
||||
AND s.slug = a.mode::text
|
||||
AND s.is_system = true
|
||||
AND a.skill_id IS NULL;
|
||||
|
||||
-- Step 6: Add RLS policy for skills table
|
||||
ALTER TABLE "skills" ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE POLICY "skills_tenant_isolation" ON "skills"
|
||||
USING (tenant_id = current_setting('app.tenant_id', true)::uuid);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
@@ -36,6 +36,13 @@
|
||||
"when": 1775856000000,
|
||||
"tag": "0004_document_source_scope",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1776364800000,
|
||||
"tag": "0005_skills_and_analysis_refactor",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user