INSIGHT-MVP/packages/crm-service/prisma/migrations/20260310_add_lexware_integration/migration.sql
Thomas Reitz 9d496d2e53 feat(crm): integrate Lexware Office for vouchers and contact sync
Adds complete Lexware Office integration to CRM service:
- Rate-limited HTTP client (Token Bucket, 2 req/s)
- Bidirectional contact sync (manual import + ERP-push)
- Voucher caching (quotes, orders, invoices, credit notes)
- Deal-voucher linking (m:n join table with audit)
- Cron jobs: voucher refresh (4h), ERP push (30min)
- Distributed locks via Redis for job deduplication
- Health check extended with Lexware status
- Prisma schema: LexwareVoucher, DealVoucher, VoucherType enum
- Companies/Contacts/Deals services extended with Lexware data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:28:41 +01:00

118 lines
4.5 KiB
SQL

-- ============================================================
-- Lexware Office Integration - Schema Migration
-- ============================================================
-- Neue Felder auf Company, Contact
-- Neue Tabellen: lexware_vouchers, deal_vouchers
-- Neuer Enum: VoucherType
-- ============================================================
-- VoucherType Enum
CREATE TYPE "app_crm"."VoucherType" AS ENUM ('QUOTATION', 'ORDER_CONFIRMATION', 'INVOICE', 'CREDIT_NOTE');
-- Company: Lexware-Felder hinzufuegen
ALTER TABLE "app_crm"."companies"
ADD COLUMN "lexware_contact_id" VARCHAR(36),
ADD COLUMN "lexware_contact_version" INTEGER,
ADD COLUMN "lexware_synced_at" TIMESTAMP(3);
-- Contact: Lexware-Felder hinzufuegen
ALTER TABLE "app_crm"."contacts"
ADD COLUMN "lexware_contact_id" VARCHAR(36),
ADD COLUMN "lexware_contact_version" INTEGER,
ADD COLUMN "lexware_synced_at" TIMESTAMP(3);
-- Unique Constraints (tenantId + lexwareContactId)
CREATE UNIQUE INDEX "companies_tenant_id_lexware_contact_id_key"
ON "app_crm"."companies"("tenant_id", "lexware_contact_id");
CREATE UNIQUE INDEX "contacts_tenant_id_lexware_contact_id_key"
ON "app_crm"."contacts"("tenant_id", "lexware_contact_id");
-- LexwareVoucher Tabelle
CREATE TABLE "app_crm"."lexware_vouchers" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"tenant_id" UUID NOT NULL,
"lexware_voucher_id" VARCHAR(36) NOT NULL,
"voucher_type" "app_crm"."VoucherType" NOT NULL,
"voucher_number" VARCHAR(100),
"voucher_date" TIMESTAMP(3),
"voucher_status" VARCHAR(50),
"total_gross_amount" DECIMAL(15,2),
"total_net_amount" DECIMAL(15,2),
"total_tax_amount" DECIMAL(15,2),
"currency" VARCHAR(3) NOT NULL DEFAULT 'EUR',
"title" VARCHAR(500),
"line_items_count" INTEGER,
"line_items_json" TEXT,
"lexware_contact_id" VARCHAR(36) NOT NULL,
"company_id" UUID,
"contact_id" UUID,
"lexware_deep_link" VARCHAR(500),
"fetched_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "lexware_vouchers_pkey" PRIMARY KEY ("id")
);
-- LexwareVoucher Indizes
CREATE UNIQUE INDEX "lexware_vouchers_tenant_id_lexware_voucher_id_key"
ON "app_crm"."lexware_vouchers"("tenant_id", "lexware_voucher_id");
CREATE INDEX "lexware_vouchers_tenant_id_idx"
ON "app_crm"."lexware_vouchers"("tenant_id");
CREATE INDEX "lexware_vouchers_tenant_id_company_id_idx"
ON "app_crm"."lexware_vouchers"("tenant_id", "company_id");
CREATE INDEX "lexware_vouchers_tenant_id_contact_id_idx"
ON "app_crm"."lexware_vouchers"("tenant_id", "contact_id");
CREATE INDEX "lexware_vouchers_tenant_id_lexware_contact_id_idx"
ON "app_crm"."lexware_vouchers"("tenant_id", "lexware_contact_id");
CREATE INDEX "lexware_vouchers_tenant_id_voucher_type_idx"
ON "app_crm"."lexware_vouchers"("tenant_id", "voucher_type");
-- LexwareVoucher Foreign Keys
ALTER TABLE "app_crm"."lexware_vouchers"
ADD CONSTRAINT "lexware_vouchers_company_id_fkey"
FOREIGN KEY ("company_id") REFERENCES "app_crm"."companies"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "app_crm"."lexware_vouchers"
ADD CONSTRAINT "lexware_vouchers_contact_id_fkey"
FOREIGN KEY ("contact_id") REFERENCES "app_crm"."contacts"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- DealVoucher Join-Tabelle
CREATE TABLE "app_crm"."deal_vouchers" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"tenant_id" UUID NOT NULL,
"deal_id" UUID NOT NULL,
"voucher_id" UUID NOT NULL,
"linked_by" UUID NOT NULL,
"linked_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "deal_vouchers_pkey" PRIMARY KEY ("id")
);
-- DealVoucher Indizes
CREATE UNIQUE INDEX "deal_vouchers_deal_id_voucher_id_key"
ON "app_crm"."deal_vouchers"("deal_id", "voucher_id");
CREATE INDEX "deal_vouchers_tenant_id_idx"
ON "app_crm"."deal_vouchers"("tenant_id");
CREATE INDEX "deal_vouchers_tenant_id_deal_id_idx"
ON "app_crm"."deal_vouchers"("tenant_id", "deal_id");
CREATE INDEX "deal_vouchers_tenant_id_voucher_id_idx"
ON "app_crm"."deal_vouchers"("tenant_id", "voucher_id");
-- DealVoucher Foreign Keys
ALTER TABLE "app_crm"."deal_vouchers"
ADD CONSTRAINT "deal_vouchers_deal_id_fkey"
FOREIGN KEY ("deal_id") REFERENCES "app_crm"."deals"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "app_crm"."deal_vouchers"
ADD CONSTRAINT "deal_vouchers_voucher_id_fkey"
FOREIGN KEY ("voucher_id") REFERENCES "app_crm"."lexware_vouchers"("id") ON DELETE CASCADE ON UPDATE CASCADE;