feat: Generisches Dokument-Upload-System fuer Entscheidungen, Normen und Falldokumente

- Neues documents-Schema mit Mandantentrennung (tenantId), Kategorien (entscheidung/norm/falldokument/sonstiges) und optionaler Verknuepfung zu cases/decisions/normInstruments
- Upload-Library (src/lib/documents/) mit Datei-Upload, PDF/DOCX-Textextraktion und gefilterten Listen
- API-Route POST/GET /api/documents mit RBAC, Audit-Logging und asynchroner Textextraktion
- Wiederverwendbare DokumentUpload-Komponente mit Drag-and-Drop, Fortschrittsanzeige und Dateiliste
- Integration in Fall-Detailseite, Entscheidungs-Detailseite und Normen-Detailseite
- Drizzle-Migration fuer documents-Tabelle mit RLS-konformer Mandantentrennung
- DSGVO: 90-Tage Aufbewahrungsfrist fuer hochgeladene Dokumente

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
CTO (LegalAI)
2026-04-09 10:18:56 +00:00
parent a8124fa6b9
commit 7b1407268b
10 changed files with 4767 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
CREATE TYPE "public"."compensation_component" AS ENUM('grundgage', 'ortszuschlag', 'kinderzuschlag', 'dienstalterszulage', 'funktionszulage', 'sonderzahlung', 'probenzuschlag');--> statement-breakpoint
CREATE TYPE "public"."contract_status" AS ENUM('aktiv', 'gekuendigt', 'nichtverlaengert', 'ausgelaufen', 'ruhend');--> statement-breakpoint
CREATE TYPE "public"."document_category" AS ENUM('entscheidung', 'norm', 'falldokument', 'sonstiges');--> statement-breakpoint
CREATE TYPE "public"."document_status" AS ENUM('uploaded', 'extracting', 'extracted', 'failed');--> statement-breakpoint
CREATE TABLE "compensation_rules" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid,
"fachgruppe_id" uuid,
"component" "compensation_component" NOT NULL,
"gagenklasse" varchar(50),
"label" varchar(255) NOT NULL,
"amount_cents" integer NOT NULL,
"min_years_of_service" integer DEFAULT 0,
"max_years_of_service" integer,
"valid_from_spielzeit" varchar(20),
"valid_to_spielzeit" varchar(20),
"legal_basis" varchar(255),
"description" text,
"sort_order" integer DEFAULT 0,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "contracts" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"case_id" uuid,
"artist_name" varchar(255) NOT NULL,
"theater_name" varchar(255) NOT NULL,
"fachgruppe_id" uuid,
"status" "contract_status" DEFAULT 'aktiv' NOT NULL,
"contract_start" date NOT NULL,
"contract_end" date NOT NULL,
"years_of_service" integer DEFAULT 0 NOT NULL,
"is_first_engagement" boolean DEFAULT false,
"is_over_55" boolean DEFAULT false,
"current_spielzeit" varchar(20),
"gagenklasse" varchar(50),
"monthly_gross_cents" integer,
"notes" text,
"metadata" jsonb,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "documents" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"user_id" uuid NOT NULL,
"category" "document_category" DEFAULT 'sonstiges' NOT NULL,
"case_id" uuid,
"decision_id" uuid,
"norm_instrument_id" uuid,
"filename" varchar(500) NOT NULL,
"mime_type" varchar(100) NOT NULL,
"file_size_bytes" integer NOT NULL,
"storage_path" text NOT NULL,
"extracted_text" text,
"status" "document_status" DEFAULT 'uploaded' NOT NULL,
"error_message" text,
"metadata" jsonb,
"delete_after" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "non_renewal_deadlines" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"contract_id" uuid NOT NULL,
"spielzeit" varchar(20) NOT NULL,
"deadline_date" date NOT NULL,
"warning_date" date,
"warning_days_before" integer DEFAULT 30,
"notice_sent" boolean DEFAULT false,
"notice_sent_date" date,
"is_auto_renewed" boolean DEFAULT false,
"legal_basis" varchar(255) NOT NULL,
"calculation_basis" text,
"protection_category" varchar(100),
"notes" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "compensation_rules" ADD CONSTRAINT "compensation_rules_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "compensation_rules" ADD CONSTRAINT "compensation_rules_fachgruppe_id_nv_buehne_fachgruppen_id_fk" FOREIGN KEY ("fachgruppe_id") REFERENCES "public"."nv_buehne_fachgruppen"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "contracts" ADD CONSTRAINT "contracts_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "contracts" ADD CONSTRAINT "contracts_case_id_cases_id_fk" FOREIGN KEY ("case_id") REFERENCES "public"."cases"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "contracts" ADD CONSTRAINT "contracts_fachgruppe_id_nv_buehne_fachgruppen_id_fk" FOREIGN KEY ("fachgruppe_id") REFERENCES "public"."nv_buehne_fachgruppen"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "documents" ADD CONSTRAINT "documents_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "documents" ADD CONSTRAINT "documents_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "documents" ADD CONSTRAINT "documents_case_id_cases_id_fk" FOREIGN KEY ("case_id") REFERENCES "public"."cases"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "documents" ADD CONSTRAINT "documents_decision_id_decisions_id_fk" FOREIGN KEY ("decision_id") REFERENCES "public"."decisions"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "documents" ADD CONSTRAINT "documents_norm_instrument_id_norm_instruments_id_fk" FOREIGN KEY ("norm_instrument_id") REFERENCES "public"."norm_instruments"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "non_renewal_deadlines" ADD CONSTRAINT "non_renewal_deadlines_contract_id_contracts_id_fk" FOREIGN KEY ("contract_id") REFERENCES "public"."contracts"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "compensation_rules_tenant_idx" ON "compensation_rules" USING btree ("tenant_id");--> statement-breakpoint
CREATE INDEX "compensation_rules_fachgruppe_idx" ON "compensation_rules" USING btree ("fachgruppe_id");--> statement-breakpoint
CREATE INDEX "compensation_rules_component_idx" ON "compensation_rules" USING btree ("component");--> statement-breakpoint
CREATE INDEX "compensation_rules_gagenklasse_idx" ON "compensation_rules" USING btree ("gagenklasse");--> statement-breakpoint
CREATE INDEX "contracts_tenant_idx" ON "contracts" USING btree ("tenant_id");--> statement-breakpoint
CREATE INDEX "contracts_case_idx" ON "contracts" USING btree ("case_id");--> statement-breakpoint
CREATE INDEX "contracts_fachgruppe_idx" ON "contracts" USING btree ("fachgruppe_id");--> statement-breakpoint
CREATE INDEX "contracts_status_idx" ON "contracts" USING btree ("status");--> statement-breakpoint
CREATE INDEX "contracts_end_idx" ON "contracts" USING btree ("contract_end");--> statement-breakpoint
CREATE INDEX "documents_tenant_idx" ON "documents" USING btree ("tenant_id");--> statement-breakpoint
CREATE INDEX "documents_case_idx" ON "documents" USING btree ("case_id");--> statement-breakpoint
CREATE INDEX "documents_decision_idx" ON "documents" USING btree ("decision_id");--> statement-breakpoint
CREATE INDEX "documents_norm_instrument_idx" ON "documents" USING btree ("norm_instrument_id");--> statement-breakpoint
CREATE INDEX "documents_category_idx" ON "documents" USING btree ("category");--> statement-breakpoint
CREATE INDEX "documents_status_idx" ON "documents" USING btree ("status");--> statement-breakpoint
CREATE INDEX "documents_delete_after_idx" ON "documents" USING btree ("delete_after");--> statement-breakpoint
CREATE INDEX "non_renewal_deadlines_contract_idx" ON "non_renewal_deadlines" USING btree ("contract_id");--> statement-breakpoint
CREATE INDEX "non_renewal_deadlines_date_idx" ON "non_renewal_deadlines" USING btree ("deadline_date");--> statement-breakpoint
CREATE INDEX "non_renewal_deadlines_spielzeit_idx" ON "non_renewal_deadlines" USING btree ("spielzeit");

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,13 @@
"when": 1775690117252,
"tag": "0001_curved_fabian_cortez",
"breakpoints": true
},
{
"idx": 2,
"version": "7",
"when": 1775729813628,
"tag": "0002_wide_grandmaster",
"breakpoints": true
}
]
}