INSIGHT-MVP/packages/crm-service/prisma/migrations/20260312_phase2_custom_fields/migration.sql
Thomas Reitz aaedf68085 feat(crm): Phase 2.1 Custom Fields — backend + frontend integration
Backend (CRM expert): Custom field definitions CRUD, bulk value upsert,
7 endpoints, Prisma schema with CustomFieldDef + CustomFieldValue tables.

Frontend: Types, API, hooks, admin settings page with field management,
CustomFieldsDisplay for detail pages, CustomFieldsForm for edit modals.
Also fix Vite allowedHosts for insight.xinion.lan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:22:57 +01:00

86 lines
3.3 KiB
SQL

-- ============================================================
-- Phase 2.1: Custom Fields System
-- Benutzerdefinierte Felder fuer PERSON, COMPANY, DEAL
-- ============================================================
-- --------------------------------------------------------
-- 1. Neue Enums
-- --------------------------------------------------------
CREATE TYPE "app_crm"."CustomFieldEntityType" AS ENUM (
'PERSON', 'COMPANY', 'DEAL'
);
CREATE TYPE "app_crm"."CustomFieldType" AS ENUM (
'TEXT', 'TEXTAREA', 'NUMBER', 'DATE',
'DROPDOWN', 'MULTI_SELECT', 'CHECKBOX', 'URL'
);
-- --------------------------------------------------------
-- 2. crm_custom_field_defs — Feld-Definitionen
-- --------------------------------------------------------
CREATE TABLE "app_crm"."crm_custom_field_defs" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"tenant_id" UUID NOT NULL,
"entity_type" "app_crm"."CustomFieldEntityType" NOT NULL,
"name" VARCHAR(200) NOT NULL,
"label" VARCHAR(200) NOT NULL,
"field_type" "app_crm"."CustomFieldType" NOT NULL,
"options" JSONB,
"is_required" BOOLEAN NOT NULL DEFAULT false,
"position" INTEGER NOT NULL DEFAULT 0,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "crm_custom_field_defs_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "crm_custom_field_defs_tenant_entity_name_key"
ON "app_crm"."crm_custom_field_defs"("tenant_id", "entity_type", "name");
CREATE INDEX "crm_custom_field_defs_tenant_id_idx"
ON "app_crm"."crm_custom_field_defs"("tenant_id");
CREATE INDEX "crm_custom_field_defs_tenant_entity_idx"
ON "app_crm"."crm_custom_field_defs"("tenant_id", "entity_type");
-- --------------------------------------------------------
-- 3. crm_custom_field_values — Feld-Werte
-- --------------------------------------------------------
CREATE TABLE "app_crm"."crm_custom_field_values" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"tenant_id" UUID NOT NULL,
"field_def_id" UUID NOT NULL,
"entity_id" UUID NOT NULL,
"value_text" TEXT,
"value_number" DECIMAL(15, 4),
"value_date" TIMESTAMP(3),
"value_boolean" BOOLEAN,
"value_json" JSONB,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "crm_custom_field_values_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "crm_custom_field_values_field_entity_key"
ON "app_crm"."crm_custom_field_values"("field_def_id", "entity_id");
CREATE INDEX "crm_custom_field_values_tenant_id_idx"
ON "app_crm"."crm_custom_field_values"("tenant_id");
CREATE INDEX "crm_custom_field_values_tenant_entity_idx"
ON "app_crm"."crm_custom_field_values"("tenant_id", "entity_id");
CREATE INDEX "crm_custom_field_values_field_def_id_idx"
ON "app_crm"."crm_custom_field_values"("field_def_id");
-- --------------------------------------------------------
-- 4. Foreign Key: Values -> Definitions (CASCADE)
-- --------------------------------------------------------
ALTER TABLE "app_crm"."crm_custom_field_values"
ADD CONSTRAINT "crm_custom_field_values_field_def_fkey"
FOREIGN KEY ("field_def_id")
REFERENCES "app_crm"."crm_custom_field_defs"("id")
ON DELETE CASCADE ON UPDATE CASCADE;