-- =============================================================================
-- Comprehensive schema sync: captures all schema evolution that happened via
-- `prisma db push` and was never written into a proper migration file.
--
-- Generated by diffing the migration-created schema against the current
-- schema.prisma using `prisma migrate diff`.
--
-- All operations are idempotent (IF NOT EXISTS / IF EXISTS / DO $$ ... $$)
-- so this migration is safe to run against both:
--   a) A fresh DB created by the prior 15 migrations (current prod state)
--   b) A DB that already had the db-push evolved schema applied
-- =============================================================================

-- =============================================================================
-- SECTION 1: New ENUM types
-- =============================================================================

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'PhoneType') THEN
    CREATE TYPE "PhoneType" AS ENUM ('DIRECT', 'MOBILE', 'HOME', 'COMPANY', 'SITE');
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'FaxType') THEN
    CREATE TYPE "FaxType" AS ENUM ('FAX', 'COMPANY', 'SITE');
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'BillingMethod') THEN
    CREATE TYPE "BillingMethod" AS ENUM ('ACTUAL_RATES', 'FIXED_FEE', 'NOT_TO_EXCEED', 'OVERRIDE_RATE');
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'BillingType') THEN
    CREATE TYPE "BillingType" AS ENUM ('STANDARD', 'PROJECT');
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'GenderType') THEN
    CREATE TYPE "GenderType" AS ENUM ('MALE', 'FEMALE');
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'USState') THEN
    CREATE TYPE "USState" AS ENUM (
      'AL','AK','AZ','AR','CA','CO','CT','DE','FL','GA','HI','ID','IL','IN',
      'IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV',
      'NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN',
      'TX','UT','VT','VA','WA','WV','WI','WY'
    );
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'Country') THEN
    CREATE TYPE "Country" AS ENUM ('US');
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'OpportunityInterest') THEN
    CREATE TYPE "OpportunityInterest" AS ENUM ('HOT', 'WARM', 'COLD');
  END IF;
END $$;

-- =============================================================================
-- SECTION 2: User table — evolve from initial flat schema to current model
-- =============================================================================

DO $$ BEGIN
  -- Remove columns no longer in schema
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'emailVerified') THEN
    ALTER TABLE "User" DROP COLUMN "emailVerified";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'name') THEN
    ALTER TABLE "User" DROP COLUMN "name";
  END IF;

  -- Add new columns
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'firstName') THEN
    ALTER TABLE "User" ADD COLUMN "firstName" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'lastName') THEN
    ALTER TABLE "User" ADD COLUMN "lastName" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'title') THEN
    ALTER TABLE "User" ADD COLUMN "title" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'active') THEN
    ALTER TABLE "User" ADD COLUMN "active" BOOLEAN NOT NULL DEFAULT true;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'hidden') THEN
    ALTER TABLE "User" ADD COLUMN "hidden" BOOLEAN NOT NULL DEFAULT false;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'cwMemberId') THEN
    ALTER TABLE "User" ADD COLUMN "cwMemberId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'User' AND column_name = 'updatedBy') THEN
    ALTER TABLE "User" ADD COLUMN "updatedBy" TEXT;
  END IF;

  -- Make userId nullable (was NOT NULL in initial migration)
  IF EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'User' AND column_name = 'userId' AND is_nullable = 'NO'
  ) THEN
    ALTER TABLE "User" ALTER COLUMN "userId" DROP NOT NULL;
  END IF;
END $$;

-- Unique indexes for new User columns (idempotent)
CREATE UNIQUE INDEX IF NOT EXISTS "User_cwIdentifier_key" ON "User"("cwIdentifier");
CREATE UNIQUE INDEX IF NOT EXISTS "User_cwMemberId_key" ON "User"("cwMemberId");

-- FK: User.cwMemberId -> CwMember.cwMemberId
DO $$ BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.table_constraints
    WHERE constraint_name = 'User_cwMemberId_fkey'
  ) THEN
    ALTER TABLE "User" ADD CONSTRAINT "User_cwMemberId_fkey"
      FOREIGN KEY ("cwMemberId") REFERENCES "CwMember"("cwMemberId") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

-- =============================================================================
-- SECTION 3: CatalogItem — change id TEXT→INTEGER, add uid PK, restructure
-- =============================================================================

-- Drop FKs that reference CatalogItem by old id column
DO $$ BEGIN
  IF EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = '_LinkedItems_A_fkey') THEN
    ALTER TABLE "_LinkedItems" DROP CONSTRAINT "_LinkedItems_A_fkey";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = '_LinkedItems_B_fkey') THEN
    ALTER TABLE "_LinkedItems" DROP CONSTRAINT "_LinkedItems_B_fkey";
  END IF;
END $$;

-- Drop old unique index that no longer applies
DROP INDEX IF EXISTS "CatalogItem_cwCatalogId_key";

-- Restructure CatalogItem
DO $$ BEGIN
  -- Add uid PK column if missing
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'uid') THEN
    ALTER TABLE "CatalogItem" ADD COLUMN "uid" TEXT NOT NULL DEFAULT '';
  END IF;

  -- Swap PK from id to uid (only if id is still the primary key)
  IF EXISTS (
    SELECT 1 FROM information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
    WHERE tc.table_name = 'CatalogItem' AND tc.constraint_type = 'PRIMARY KEY' AND kcu.column_name = 'id'
  ) THEN
    ALTER TABLE "CatalogItem" DROP CONSTRAINT "CatalogItem_pkey";
    ALTER TABLE "CatalogItem" ADD CONSTRAINT "CatalogItem_pkey" PRIMARY KEY ("uid");
  END IF;

  -- Change id from TEXT to INTEGER (only if still TEXT)
  IF EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'CatalogItem' AND column_name = 'id' AND data_type = 'text'
  ) THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "id";
    ALTER TABLE "CatalogItem" ADD COLUMN "id" INTEGER;
  END IF;

  -- Drop old columns no longer in schema
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'cwCatalogId') THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "cwCatalogId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'category') THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "category";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'categoryCwId') THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "categoryCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'manufacturer') THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "manufacturer";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'manufactureCwId') THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "manufactureCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'subcategory') THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "subcategory";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'subcategoryCwId') THEN
    ALTER TABLE "CatalogItem" DROP COLUMN "subcategoryCwId";
  END IF;

  -- Add new columns
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'classId') THEN
    ALTER TABLE "CatalogItem" ADD COLUMN "classId" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'manufacturerId') THEN
    ALTER TABLE "CatalogItem" ADD COLUMN "manufacturerId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'CatalogItem' AND column_name = 'subcategoryId') THEN
    ALTER TABLE "CatalogItem" ADD COLUMN "subcategoryId" INTEGER NOT NULL DEFAULT 0;
  END IF;
END $$;

CREATE UNIQUE INDEX IF NOT EXISTS "CatalogItem_id_key" ON "CatalogItem"("id");

-- =============================================================================
-- SECTION 4: Company — change id TEXT→INTEGER, add uid PK, add columns
-- Production has ~4500 rows with CUID text PKs and cw_CompanyId integers
-- that must be preserved as uid and id respectively.
-- =============================================================================

-- Drop FKs that reference Company by old id
DO $$ BEGIN
  IF EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Credential_companyId_fkey') THEN
    ALTER TABLE "Credential" DROP CONSTRAINT "Credential_companyId_fkey";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'UnifiSite_companyId_fkey') THEN
    ALTER TABLE "UnifiSite" DROP CONSTRAINT "UnifiSite_companyId_fkey";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_companyId_fkey') THEN
    ALTER TABLE "Opportunity" DROP CONSTRAINT "Opportunity_companyId_fkey";
  END IF;
END $$;

DROP INDEX IF EXISTS "Company_cw_CompanyId_key";
DROP INDEX IF EXISTS "Company_cw_Identifier_key";

DO $$ BEGIN
  -- Step 1: Add uid as NULLABLE (no default) so existing rows stay NULL temporarily
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'uid') THEN
    ALTER TABLE "Company" ADD COLUMN "uid" TEXT;
  END IF;

  -- Step 2: Populate uid from the old text PK (old id was a CUID — it becomes uid)
  UPDATE "Company" SET "uid" = "id" WHERE "uid" IS NULL;

  -- Step 3: Now make uid NOT NULL (all rows are populated)
  ALTER TABLE "Company" ALTER COLUMN "uid" SET NOT NULL;

  -- Step 4: Swap PK from id (text) to uid (text)
  IF EXISTS (
    SELECT 1 FROM information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
    WHERE tc.table_name = 'Company' AND tc.constraint_type = 'PRIMARY KEY' AND kcu.column_name = 'id'
  ) THEN
    ALTER TABLE "Company" DROP CONSTRAINT "Company_pkey";
    ALTER TABLE "Company" ADD CONSTRAINT "Company_pkey" PRIMARY KEY ("uid");
  END IF;

  -- Step 5: Change id from TEXT to INTEGER
  -- NOTE: do this BEFORE dropping cw_CompanyId so we can populate from it below
  IF EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'Company' AND column_name = 'id' AND data_type = 'text'
  ) THEN
    ALTER TABLE "Company" DROP COLUMN "id";
    ALTER TABLE "Company" ADD COLUMN "id" INTEGER;
  END IF;

  -- Step 6: Populate new integer id from cw_CompanyId (CW integer company id)
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'cw_CompanyId') THEN
    UPDATE "Company" SET "id" = "cw_CompanyId" WHERE "id" IS NULL;
  END IF;

  -- Step 7: Drop old CW-specific columns (data now in id and uid)
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'cw_CompanyId') THEN
    ALTER TABLE "Company" DROP COLUMN "cw_CompanyId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'cw_Identifier') THEN
    ALTER TABLE "Company" DROP COLUMN "cw_Identifier";
  END IF;

  -- Step 8: Add new columns
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'dateDeleted') THEN
    ALTER TABLE "Company" ADD COLUMN "dateDeleted" TIMESTAMP(3);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'deleteFlag') THEN
    ALTER TABLE "Company" ADD COLUMN "deleteFlag" BOOLEAN NOT NULL DEFAULT false;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'deletedAt') THEN
    ALTER TABLE "Company" ADD COLUMN "deletedAt" TIMESTAMP(3);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'deletedById') THEN
    ALTER TABLE "Company" ADD COLUMN "deletedById" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'enteredById') THEN
    ALTER TABLE "Company" ADD COLUMN "enteredById" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'phone') THEN
    ALTER TABLE "Company" ADD COLUMN "phone" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'taxExempt') THEN
    ALTER TABLE "Company" ADD COLUMN "taxExempt" BOOLEAN NOT NULL DEFAULT false;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'taxId') THEN
    ALTER TABLE "Company" ADD COLUMN "taxId" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Company' AND column_name = 'website') THEN
    ALTER TABLE "Company" ADD COLUMN "website" TEXT;
  END IF;
END $$;

-- Make Company.id NOT NULL (all rows were populated from cw_CompanyId above)
ALTER TABLE "Company" ALTER COLUMN "id" SET NOT NULL;
CREATE UNIQUE INDEX IF NOT EXISTS "Company_id_key" ON "Company"("id");

-- =============================================================================
-- SECTION 5: UnifiSite — change companyId from TEXT to INTEGER (data migration)
-- Production has ~180 rows where companyId (text) = Company.uid (the old text
-- PK that was copied into uid in Section 4). We join on Company.uid to get
-- the new integer Company.id and preserve the relationship.
-- =============================================================================

DO $$ BEGIN
  IF EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'UnifiSite' AND column_name = 'companyId' AND data_type = 'text'
  ) THEN
    -- Add a temporary integer column to hold the mapped value
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'UnifiSite' AND column_name = 'companyId_int') THEN
      ALTER TABLE "UnifiSite" ADD COLUMN "companyId_int" INTEGER;
    END IF;
    -- Map old text companyId (= Company.uid) → new integer Company.id
    UPDATE "UnifiSite" us
    SET "companyId_int" = c."id"
    FROM "Company" c
    WHERE c."uid" = us."companyId";
    -- Replace old text column with the populated integer column
    ALTER TABLE "UnifiSite" DROP COLUMN "companyId";
    ALTER TABLE "UnifiSite" RENAME COLUMN "companyId_int" TO "companyId";
  ELSIF EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'UnifiSite' AND column_name = 'companyId_int'
  ) THEN
    -- Edge case: int column added but not renamed (interrupted previous run)
    ALTER TABLE "UnifiSite" RENAME COLUMN "companyId_int" TO "companyId";
  END IF;
END $$;

-- =============================================================================
-- SECTION 6: Opportunity — full restructure
-- =============================================================================

-- Drop FKs referencing Opportunity by old id/companyId
DO $$ BEGIN
  IF EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'GeneratedQuotes_opportunityId_fkey') THEN
    ALTER TABLE "GeneratedQuotes" DROP CONSTRAINT "GeneratedQuotes_opportunityId_fkey";
  END IF;
END $$;

DROP INDEX IF EXISTS "Opportunity_cwOpportunityId_key";

DO $$ BEGIN
  -- Add uid PK column if missing
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'uid') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "uid" TEXT NOT NULL DEFAULT '';
  END IF;

  -- Swap PK from id to uid
  IF EXISTS (
    SELECT 1 FROM information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
    WHERE tc.table_name = 'Opportunity' AND tc.constraint_type = 'PRIMARY KEY' AND kcu.column_name = 'id'
  ) THEN
    ALTER TABLE "Opportunity" DROP CONSTRAINT "Opportunity_pkey";
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_pkey" PRIMARY KEY ("uid");
  END IF;

  -- Change id from TEXT to INTEGER
  IF EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'Opportunity' AND column_name = 'id' AND data_type = 'text'
  ) THEN
    ALTER TABLE "Opportunity" DROP COLUMN "id";
    ALTER TABLE "Opportunity" ADD COLUMN "id" INTEGER;
  END IF;

  -- Change companyId from TEXT to INTEGER
  IF EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'Opportunity' AND column_name = 'companyId' AND data_type = 'text'
  ) THEN
    ALTER TABLE "Opportunity" DROP COLUMN "companyId";
    ALTER TABLE "Opportunity" ADD COLUMN "companyId" INTEGER;
  END IF;

  -- Drop old flat/CW columns
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'cwOpportunityId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "cwOpportunityId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'campaignCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "campaignCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'campaignName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "campaignName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'closedByCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "closedByCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'closedByName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "closedByName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'companyCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "companyCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'companyName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "companyName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'contactCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "contactCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'contactName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "contactName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'cwLastUpdated') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "cwLastUpdated";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'departmentCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "departmentCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'departmentName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "departmentName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'locationCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "locationCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'locationName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "locationName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'primarySalesRepCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "primarySalesRepCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'primarySalesRepIdentifier') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "primarySalesRepIdentifier";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'primarySalesRepName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "primarySalesRepName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'priorityCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "priorityCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'priorityName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "priorityName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'ratingCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "ratingCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'ratingName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "ratingName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'secondarySalesRepCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "secondarySalesRepCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'secondarySalesRepIdentifier') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "secondarySalesRepIdentifier";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'secondarySalesRepName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "secondarySalesRepName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'siteCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "siteCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'siteName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "siteName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'statusCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "statusCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'statusName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "statusName";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'totalSalesTax') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "totalSalesTax";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'typeCwId') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "typeCwId";
  END IF;
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'typeName') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "typeName";
  END IF;

  -- Add new columns
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'closedById') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "closedById" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'contactId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "contactId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'departmentId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "departmentId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'eneteredBy') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "eneteredBy" TEXT NOT NULL DEFAULT '';
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'interest') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "interest" "OpportunityInterest";
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'locationId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "locationId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'oppNarrative') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "oppNarrative" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'primarySalesRepId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "primarySalesRepId" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'secondarySalesRepId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "secondarySalesRepId" TEXT;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'siteId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "siteId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'statusId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "statusId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'taxCodeId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "taxCodeId" INTEGER;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'typeId') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "typeId" INTEGER NOT NULL DEFAULT 0;
  END IF;
  IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'updatedBy') THEN
    ALTER TABLE "Opportunity" ADD COLUMN "updatedBy" TEXT NOT NULL DEFAULT '';
  END IF;
END $$;

CREATE UNIQUE INDEX IF NOT EXISTS "Opportunity_id_key" ON "Opportunity"("id");

-- =============================================================================
-- SECTION 7: New tables (all idempotent via IF NOT EXISTS)
-- =============================================================================

CREATE TABLE IF NOT EXISTS "CorporateLocation" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "updatedById" TEXT,
    "addressLine1" TEXT,
    "addressLine2" TEXT,
    "city" TEXT,
    "state" "USState",
    "zipCode" TEXT,
    "country" "Country",
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "CorporateLocation_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "CorporateLocation_id_key" ON "CorporateLocation"("id");

CREATE TABLE IF NOT EXISTS "InternalDepartment" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "createdById" TEXT,
    "updatedById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "InternalDepartment_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "InternalDepartment_id_key" ON "InternalDepartment"("id");

CREATE TABLE IF NOT EXISTS "CompanyAddress" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "addressLine1" TEXT,
    "addressLine2" TEXT,
    "city" TEXT,
    "state" "USState",
    "zipCode" TEXT,
    "country" "Country",
    "phone" TEXT,
    "fax" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultMailFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultBillFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultShipFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "companyId" INTEGER NOT NULL,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "CompanyAddress_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "CompanyAddress_id_key" ON "CompanyAddress"("id");

CREATE TABLE IF NOT EXISTS "Contact" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "active" BOOLEAN NOT NULL DEFAULT true,
    "default" BOOLEAN NOT NULL DEFAULT false,
    "firstName" TEXT NOT NULL,
    "lastName" TEXT NOT NULL,
    "nickname" TEXT,
    "title" TEXT,
    "gender" "GenderType",
    "birthday" TIMESTAMP(3),
    "email" TEXT,
    "phone" TEXT,
    "phoneExtension" TEXT,
    "phoneType" "PhoneType",
    "companyAddressId" INTEGER,
    "memberId" INTEGER,
    "companyId" INTEGER,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "Contact_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "Contact_id_key" ON "Contact"("id");

CREATE TABLE IF NOT EXISTS "CatalogItemType" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "CatalogItemType_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "CatalogItemType_id_key" ON "CatalogItemType"("id");

CREATE TABLE IF NOT EXISTS "CatalogCategory" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "CatalogCategory_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "CatalogCategory_id_key" ON "CatalogCategory"("id");

CREATE TABLE IF NOT EXISTS "CatalogSubcategory" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "categoryId" INTEGER NOT NULL,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "CatalogSubcategory_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "CatalogSubcategory_id_key" ON "CatalogSubcategory"("id");

CREATE TABLE IF NOT EXISTS "CatalogManufacturer" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "CatalogManufacturer_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "CatalogManufacturer_id_key" ON "CatalogManufacturer"("id");

CREATE TABLE IF NOT EXISTS "Warehouse" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "lockedFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "Warehouse_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "Warehouse_id_key" ON "Warehouse"("id");

CREATE TABLE IF NOT EXISTS "WarehouseBin" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "minQuantity" INTEGER NOT NULL,
    "maxQuantity" INTEGER NOT NULL,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "warehouseId" INTEGER,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "WarehouseBin_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "WarehouseBin_id_key" ON "WarehouseBin"("id");

CREATE TABLE IF NOT EXISTS "ProductInventory" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "qtyOnHand" INTEGER NOT NULL DEFAULT 0,
    "warehouseBinId" INTEGER NOT NULL,
    "itemId" INTEGER,
    "warehouseId" INTEGER,
    "updatedById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ProductInventory_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ProductInventory_id_key" ON "ProductInventory"("id");

CREATE TABLE IF NOT EXISTS "MinimumStockByWarehouse" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "minQty" INTEGER NOT NULL DEFAULT 0,
    "warehouseId" INTEGER NOT NULL,
    "itemId" INTEGER,
    "updatedById" TEXT,
    "enteredById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "MinimumStockByWarehouse_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "MinimumStockByWarehouse_id_key" ON "MinimumStockByWarehouse"("id");

CREATE TABLE IF NOT EXISTS "ProductData" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "qty" DOUBLE PRECISION NOT NULL DEFAULT 1,
    "internalNote" TEXT,
    "shortDescription" TEXT,
    "description" TEXT,
    "sequenceNumber" INTEGER,
    "procurementNotes" TEXT,
    "productNarrative" TEXT,
    "unitPrice" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "unitCost" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "listPrice" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "discount" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "recurringRevenue" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "recurringCost" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "qtyPicked" INTEGER NOT NULL DEFAULT 0,
    "qtyShipped" INTEGER NOT NULL DEFAULT 0,
    "cancelReason" TEXT,
    "cancelQty" DOUBLE PRECISION,
    "billableFlag" BOOLEAN NOT NULL DEFAULT true,
    "taxableFlag" BOOLEAN NOT NULL DEFAULT true,
    "invoiceFlag" BOOLEAN NOT NULL DEFAULT true,
    "recurringFlag" BOOLEAN NOT NULL DEFAULT false,
    "poApprovedFlag" BOOLEAN NOT NULL DEFAULT false,
    "calcPriceFlag" BOOLEAN NOT NULL DEFAULT true,
    "calcCostFlag" BOOLEAN NOT NULL DEFAULT true,
    "cancelFlag" BOOLEAN NOT NULL DEFAULT false,
    "catalogItemId" INTEGER NOT NULL,
    "corporateLocationId" INTEGER NOT NULL,
    "serviceTicketId" INTEGER,
    "opportunityId" INTEGER,
    "updatedById" TEXT,
    "createdById" TEXT,
    "closedById" TEXT,
    "cancelById" TEXT NOT NULL DEFAULT '',
    "closedAt" TIMESTAMP(3),
    "cancelledAt" TIMESTAMP(3),
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ProductData_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ProductData_id_key" ON "ProductData"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketLocation" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketLocation_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketLocation_id_key" ON "ServiceTicketLocation"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketSource" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketSource_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketSource_id_key" ON "ServiceTicketSource"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketImpact" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketImpact_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketImpact_id_key" ON "ServiceTicketImpact"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketPriority" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "color" TEXT,
    "description" TEXT,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketPriority_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketPriority_id_key" ON "ServiceTicketPriority"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketServerity" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketServerity_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketServerity_id_key" ON "ServiceTicketServerity"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketBoard" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "timeBillableFlag" BOOLEAN NOT NULL DEFAULT false,
    "expenseBillableFlag" BOOLEAN NOT NULL DEFAULT false,
    "productBillableFlag" BOOLEAN NOT NULL DEFAULT false,
    "timeInvoiceableFlag" BOOLEAN NOT NULL DEFAULT false,
    "expenseInvoiceableFlag" BOOLEAN NOT NULL DEFAULT false,
    "productInvoiceableFlag" BOOLEAN NOT NULL DEFAULT false,
    "autoAssignNewFlag" BOOLEAN NOT NULL DEFAULT false,
    "autoAssignEmailCreatedFlag" BOOLEAN NOT NULL DEFAULT false,
    "autoAssignPortalCreatedFlag" BOOLEAN NOT NULL DEFAULT false,
    "projectFlag" BOOLEAN NOT NULL DEFAULT false,
    "lockDescriptionFlag" BOOLEAN NOT NULL DEFAULT false,
    "emailContactFlag" BOOLEAN NOT NULL DEFAULT false,
    "emailResourceFlag" BOOLEAN NOT NULL DEFAULT false,
    "resolutionSortOrder" CHAR(1) NOT NULL DEFAULT 'D',
    "internalAnalysisSortOrder" CHAR(1) NOT NULL DEFAULT 'D',
    "locationId" INTEGER NOT NULL,
    "createdById" TEXT,
    "updatedById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketBoard_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketBoard_id_key" ON "ServiceTicketBoard"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketType" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketType_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketType_id_key" ON "ServiceTicketType"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicket" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "summary" TEXT NOT NULL,
    "addressLine1" TEXT,
    "addressLine2" TEXT,
    "city" TEXT,
    "state" "USState",
    "zipCode" TEXT,
    "country" "Country",
    "contactName" TEXT,
    "phone" TEXT,
    "phoneExtension" TEXT,
    "phoneType" "PhoneType",
    "email" TEXT,
    "poNumber" TEXT,
    "billCompleteFlag" BOOLEAN NOT NULL DEFAULT false,
    "billUnapprovedFlag" BOOLEAN NOT NULL DEFAULT false,
    "billingAmount" DOUBLE PRECISION NOT NULL DEFAULT 0.00,
    "billingMethod" "BillingMethod" NOT NULL DEFAULT 'ACTUAL_RATES',
    "timeBillableFlag" BOOLEAN NOT NULL DEFAULT true,
    "expenseBillableFlag" BOOLEAN NOT NULL DEFAULT true,
    "productBillableFlag" BOOLEAN NOT NULL DEFAULT true,
    "timeInvoiceableFlag" BOOLEAN NOT NULL DEFAULT true,
    "expenseInvoiceableFlag" BOOLEAN NOT NULL DEFAULT true,
    "productInvoiceableFlag" BOOLEAN NOT NULL DEFAULT true,
    "dateRequested" TIMESTAMP(3),
    "billingType" "BillingType" NOT NULL DEFAULT 'STANDARD',
    "billingInstructions" TEXT,
    "rejectedFlag" BOOLEAN NOT NULL DEFAULT false,
    "closedFlag" BOOLEAN NOT NULL DEFAULT false,
    "redFlag" BOOLEAN NOT NULL DEFAULT false,
    "publishFlag" BOOLEAN NOT NULL DEFAULT false,
    "ticketOwnerId" TEXT,
    "serviceTicketBoardId" INTEGER,
    "severityId" INTEGER NOT NULL DEFAULT 0,
    "impactId" INTEGER NOT NULL DEFAULT 0,
    "priorityId" INTEGER NOT NULL DEFAULT 0,
    "sourceId" INTEGER NOT NULL DEFAULT 0,
    "locationId" INTEGER NOT NULL DEFAULT 0,
    "parentId" INTEGER,
    "companyId" INTEGER,
    "contactId" INTEGER,
    "companyAddressId" INTEGER,
    "billingCompanyId" INTEGER,
    "billingAddressId" INTEGER,
    "createdById" TEXT,
    "updatedById" TEXT,
    "closedById" TEXT,
    "rejectedAt" TIMESTAMP(3),
    "closedAt" TIMESTAMP(3),
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicket_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicket_id_key" ON "ServiceTicket"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketNote" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "notes" TEXT NOT NULL,
    "notesMd" TEXT NOT NULL,
    "authorId" TEXT NOT NULL,
    "problemFlag" BOOLEAN NOT NULL DEFAULT false,
    "resolutionFlag" BOOLEAN NOT NULL DEFAULT false,
    "internalAnalysisFlag" BOOLEAN NOT NULL DEFAULT false,
    "internalMemberFlag" BOOLEAN NOT NULL DEFAULT false,
    "createdByParentFlag" BOOLEAN NOT NULL DEFAULT false,
    "mergedFlag" BOOLEAN NOT NULL DEFAULT false,
    "bundledFlag" BOOLEAN NOT NULL DEFAULT false,
    "serviceTicketId" INTEGER NOT NULL,
    "createdById" TEXT,
    "updatedById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ServiceTicketNote_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ServiceTicketNote_id_key" ON "ServiceTicketNote"("id");

CREATE TABLE IF NOT EXISTS "ServiceTicketFinalData" (
    "id" TEXT NOT NULL,
    CONSTRAINT "ServiceTicketFinalData_pkey" PRIMARY KEY ("id")
);

CREATE TABLE IF NOT EXISTS "OpportunityType" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "OpportunityType_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "OpportunityType_id_key" ON "OpportunityType"("id");

CREATE TABLE IF NOT EXISTS "OpportunityStatus" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "inactiveFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "wonFlag" BOOLEAN NOT NULL DEFAULT false,
    "lostFlag" BOOLEAN NOT NULL DEFAULT false,
    "closeFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "OpportunityStatus_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "OpportunityStatus_id_key" ON "OpportunityStatus"("id");

CREATE TABLE IF NOT EXISTS "ScheduleStatus" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "color" TEXT,
    "softFlag" BOOLEAN NOT NULL DEFAULT false,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ScheduleStatus_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ScheduleStatus_id_key" ON "ScheduleStatus"("id");

CREATE TABLE IF NOT EXISTS "ScheduleType" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "displayColor" TEXT,
    "tableReference" TEXT,
    "moduleId" CHAR(2),
    "scheduleTypeId" CHAR(1),
    "systemFlag" BOOLEAN NOT NULL DEFAULT false,
    "displayFlag" BOOLEAN NOT NULL DEFAULT false,
    "updatedById" TEXT,
    "createdById" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "ScheduleType_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "ScheduleType_id_key" ON "ScheduleType"("id");

CREATE TABLE IF NOT EXISTS "ScheduleSpan" (
    "id" SERIAL NOT NULL,
    "scheduleSpanId" CHAR(1),
    "spanDesc" CHAR(20),
    CONSTRAINT "ScheduleSpan_pkey" PRIMARY KEY ("id")
);

CREATE TABLE IF NOT EXISTS "Schedule" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "name" TEXT NOT NULL,
    "description" TEXT,
    "memberId" TEXT,
    "closedFlag" BOOLEAN NOT NULL DEFAULT false,
    "reminderFlag" BOOLEAN NOT NULL DEFAULT false,
    "allDayFlag" BOOLEAN NOT NULL DEFAULT false,
    "acknowledgementFlag" BOOLEAN NOT NULL DEFAULT false,
    "meetingFlag" BOOLEAN NOT NULL DEFAULT false,
    "recurringFlag" BOOLEAN NOT NULL DEFAULT false,
    "billableFlag" BOOLEAN NOT NULL DEFAULT false,
    "acknowledgedById" TEXT,
    "acknowledgedAt" TIMESTAMP(3),
    "startDate" TIMESTAMP(3),
    "endDate" TIMESTAMP(3),
    "hoursScheduled" DOUBLE PRECISION,
    "duration" INTEGER,
    "hoursPerDay" DOUBLE PRECISION,
    "reminderMinutes" INTEGER DEFAULT 15,
    "statusId" INTEGER,
    "typeId" INTEGER,
    "scheduleSpanId" INTEGER,
    "updatedById" TEXT,
    "createdById" TEXT,
    "closedById" TEXT,
    "closedAt" TIMESTAMP(3),
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "Schedule_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "Schedule_id_key" ON "Schedule"("id");

CREATE TABLE IF NOT EXISTS "TaxCode" (
    "id" INTEGER NOT NULL,
    "uid" TEXT NOT NULL,
    "code" TEXT NOT NULL,
    "codeCaption" TEXT NOT NULL,
    "description" TEXT,
    "rate" DOUBLE PRECISION,
    "defaultFlag" BOOLEAN NOT NULL DEFAULT false,
    "createdBy" TEXT NOT NULL DEFAULT '',
    "updatedBy" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    CONSTRAINT "TaxCode_pkey" PRIMARY KEY ("uid")
);
CREATE UNIQUE INDEX IF NOT EXISTS "TaxCode_id_key" ON "TaxCode"("id");
CREATE UNIQUE INDEX IF NOT EXISTS "TaxCode_code_key" ON "TaxCode"("code");

-- =============================================================================
-- SECTION 8: Foreign keys (all idempotent via DO $$ ... $$)
-- =============================================================================

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'UnifiSite_companyId_fkey') THEN
    ALTER TABLE "UnifiSite" ADD CONSTRAINT "UnifiSite_companyId_fkey"
      FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Company_deletedById_fkey') THEN
    ALTER TABLE "Company" ADD CONSTRAINT "Company_deletedById_fkey"
      FOREIGN KEY ("deletedById") REFERENCES "User"("cwIdentifier") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Company_enteredById_fkey') THEN
    ALTER TABLE "Company" ADD CONSTRAINT "Company_enteredById_fkey"
      FOREIGN KEY ("enteredById") REFERENCES "User"("cwIdentifier") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'CompanyAddress_updatedById_fkey') THEN
    ALTER TABLE "CompanyAddress" ADD CONSTRAINT "CompanyAddress_updatedById_fkey"
      FOREIGN KEY ("updatedById") REFERENCES "User"("cwIdentifier") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'CompanyAddress_companyId_fkey') THEN
    ALTER TABLE "CompanyAddress" ADD CONSTRAINT "CompanyAddress_companyId_fkey"
      FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Contact_companyAddressId_fkey') THEN
    ALTER TABLE "Contact" ADD CONSTRAINT "Contact_companyAddressId_fkey"
      FOREIGN KEY ("companyAddressId") REFERENCES "CompanyAddress"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Contact_companyId_fkey') THEN
    ALTER TABLE "Contact" ADD CONSTRAINT "Contact_companyId_fkey"
      FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'CatalogSubcategory_categoryId_fkey') THEN
    ALTER TABLE "CatalogSubcategory" ADD CONSTRAINT "CatalogSubcategory_categoryId_fkey"
      FOREIGN KEY ("categoryId") REFERENCES "CatalogCategory"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'WarehouseBin_warehouseId_fkey') THEN
    ALTER TABLE "WarehouseBin" ADD CONSTRAINT "WarehouseBin_warehouseId_fkey"
      FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ProductInventory_warehouseBinId_fkey') THEN
    ALTER TABLE "ProductInventory" ADD CONSTRAINT "ProductInventory_warehouseBinId_fkey"
      FOREIGN KEY ("warehouseBinId") REFERENCES "WarehouseBin"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ProductInventory_itemId_fkey') THEN
    ALTER TABLE "ProductInventory" ADD CONSTRAINT "ProductInventory_itemId_fkey"
      FOREIGN KEY ("itemId") REFERENCES "CatalogItem"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ProductInventory_warehouseId_fkey') THEN
    ALTER TABLE "ProductInventory" ADD CONSTRAINT "ProductInventory_warehouseId_fkey"
      FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'MinimumStockByWarehouse_warehouseId_fkey') THEN
    ALTER TABLE "MinimumStockByWarehouse" ADD CONSTRAINT "MinimumStockByWarehouse_warehouseId_fkey"
      FOREIGN KEY ("warehouseId") REFERENCES "Warehouse"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'MinimumStockByWarehouse_itemId_fkey') THEN
    ALTER TABLE "MinimumStockByWarehouse" ADD CONSTRAINT "MinimumStockByWarehouse_itemId_fkey"
      FOREIGN KEY ("itemId") REFERENCES "CatalogItem"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'CatalogItem_subcategoryId_fkey') THEN
    ALTER TABLE "CatalogItem" ADD CONSTRAINT "CatalogItem_subcategoryId_fkey"
      FOREIGN KEY ("subcategoryId") REFERENCES "CatalogSubcategory"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'CatalogItem_manufacturerId_fkey') THEN
    ALTER TABLE "CatalogItem" ADD CONSTRAINT "CatalogItem_manufacturerId_fkey"
      FOREIGN KEY ("manufacturerId") REFERENCES "CatalogManufacturer"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ProductData_serviceTicketId_fkey') THEN
    ALTER TABLE "ProductData" ADD CONSTRAINT "ProductData_serviceTicketId_fkey"
      FOREIGN KEY ("serviceTicketId") REFERENCES "ServiceTicket"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ProductData_opportunityId_fkey') THEN
    ALTER TABLE "ProductData" ADD CONSTRAINT "ProductData_opportunityId_fkey"
      FOREIGN KEY ("opportunityId") REFERENCES "Opportunity"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ProductData_catalogItemId_fkey') THEN
    ALTER TABLE "ProductData" ADD CONSTRAINT "ProductData_catalogItemId_fkey"
      FOREIGN KEY ("catalogItemId") REFERENCES "CatalogItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ProductData_corporateLocationId_fkey') THEN
    ALTER TABLE "ProductData" ADD CONSTRAINT "ProductData_corporateLocationId_fkey"
      FOREIGN KEY ("corporateLocationId") REFERENCES "CorporateLocation"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_severityId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_severityId_fkey"
      FOREIGN KEY ("severityId") REFERENCES "ServiceTicketServerity"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_impactId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_impactId_fkey"
      FOREIGN KEY ("impactId") REFERENCES "ServiceTicketImpact"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_priorityId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_priorityId_fkey"
      FOREIGN KEY ("priorityId") REFERENCES "ServiceTicketPriority"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_sourceId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_sourceId_fkey"
      FOREIGN KEY ("sourceId") REFERENCES "ServiceTicketSource"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_locationId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_locationId_fkey"
      FOREIGN KEY ("locationId") REFERENCES "ServiceTicketLocation"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_serviceTicketBoardId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_serviceTicketBoardId_fkey"
      FOREIGN KEY ("serviceTicketBoardId") REFERENCES "ServiceTicketBoard"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_ticketOwnerId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_ticketOwnerId_fkey"
      FOREIGN KEY ("ticketOwnerId") REFERENCES "User"("cwIdentifier") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_companyId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_companyId_fkey"
      FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_contactId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_contactId_fkey"
      FOREIGN KEY ("contactId") REFERENCES "Contact"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_companyAddressId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_companyAddressId_fkey"
      FOREIGN KEY ("companyAddressId") REFERENCES "CompanyAddress"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_billingCompanyId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_billingCompanyId_fkey"
      FOREIGN KEY ("billingCompanyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_billingAddressId_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_billingAddressId_fkey"
      FOREIGN KEY ("billingAddressId") REFERENCES "CompanyAddress"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_closedById_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_closedById_fkey"
      FOREIGN KEY ("closedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_createdById_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_createdById_fkey"
      FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicket_updatedById_fkey') THEN
    ALTER TABLE "ServiceTicket" ADD CONSTRAINT "ServiceTicket_updatedById_fkey"
      FOREIGN KEY ("updatedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicketNote_authorId_fkey') THEN
    ALTER TABLE "ServiceTicketNote" ADD CONSTRAINT "ServiceTicketNote_authorId_fkey"
      FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicketNote_serviceTicketId_fkey') THEN
    ALTER TABLE "ServiceTicketNote" ADD CONSTRAINT "ServiceTicketNote_serviceTicketId_fkey"
      FOREIGN KEY ("serviceTicketId") REFERENCES "ServiceTicket"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'ServiceTicketBoard_locationId_fkey') THEN
    ALTER TABLE "ServiceTicketBoard" ADD CONSTRAINT "ServiceTicketBoard_locationId_fkey"
      FOREIGN KEY ("locationId") REFERENCES "CorporateLocation"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_typeId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_typeId_fkey"
      FOREIGN KEY ("typeId") REFERENCES "OpportunityType"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_statusId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_statusId_fkey"
      FOREIGN KEY ("statusId") REFERENCES "OpportunityStatus"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_taxCodeId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_taxCodeId_fkey"
      FOREIGN KEY ("taxCodeId") REFERENCES "TaxCode"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_primarySalesRepId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_primarySalesRepId_fkey"
      FOREIGN KEY ("primarySalesRepId") REFERENCES "User"("cwIdentifier") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_secondarySalesRepId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_secondarySalesRepId_fkey"
      FOREIGN KEY ("secondarySalesRepId") REFERENCES "User"("cwIdentifier") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_companyId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_companyId_fkey"
      FOREIGN KEY ("companyId") REFERENCES "Company"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_contactId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_contactId_fkey"
      FOREIGN KEY ("contactId") REFERENCES "Contact"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_siteId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_siteId_fkey"
      FOREIGN KEY ("siteId") REFERENCES "CompanyAddress"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_locationId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_locationId_fkey"
      FOREIGN KEY ("locationId") REFERENCES "CorporateLocation"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Opportunity_departmentId_fkey') THEN
    ALTER TABLE "Opportunity" ADD CONSTRAINT "Opportunity_departmentId_fkey"
      FOREIGN KEY ("departmentId") REFERENCES "InternalDepartment"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Schedule_statusId_fkey') THEN
    ALTER TABLE "Schedule" ADD CONSTRAINT "Schedule_statusId_fkey"
      FOREIGN KEY ("statusId") REFERENCES "ScheduleStatus"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Schedule_typeId_fkey') THEN
    ALTER TABLE "Schedule" ADD CONSTRAINT "Schedule_typeId_fkey"
      FOREIGN KEY ("typeId") REFERENCES "ScheduleType"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Schedule_scheduleSpanId_fkey') THEN
    ALTER TABLE "Schedule" ADD CONSTRAINT "Schedule_scheduleSpanId_fkey"
      FOREIGN KEY ("scheduleSpanId") REFERENCES "ScheduleSpan"("id") ON DELETE SET NULL ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'Credential_companyId_fkey') THEN
    ALTER TABLE "Credential" ADD CONSTRAINT "Credential_companyId_fkey"
      FOREIGN KEY ("companyId") REFERENCES "Company"("uid") ON DELETE CASCADE ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'GeneratedQuotes_opportunityId_fkey') THEN
    ALTER TABLE "GeneratedQuotes" ADD CONSTRAINT "GeneratedQuotes_opportunityId_fkey"
      FOREIGN KEY ("opportunityId") REFERENCES "Opportunity"("uid") ON DELETE CASCADE ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = '_LinkedItems_A_fkey') THEN
    ALTER TABLE "_LinkedItems" ADD CONSTRAINT "_LinkedItems_A_fkey"
      FOREIGN KEY ("A") REFERENCES "CatalogItem"("uid") ON DELETE CASCADE ON UPDATE CASCADE;
  END IF;
END $$;

DO $$ BEGIN
  IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = '_LinkedItems_B_fkey') THEN
    ALTER TABLE "_LinkedItems" ADD CONSTRAINT "_LinkedItems_B_fkey"
      FOREIGN KEY ("B") REFERENCES "CatalogItem"("uid") ON DELETE CASCADE ON UPDATE CASCADE;
  END IF;
END $$;

-- =============================================================================
-- SECTION 9: Cleanup — drop temporary defaults added for idempotency,
--            enforce NOT NULL on new integer id columns, drop removed columns
-- =============================================================================

-- CatalogItem: drop defaults, enforce NOT NULL
ALTER TABLE "CatalogItem" ALTER COLUMN "uid" DROP DEFAULT;
ALTER TABLE "CatalogItem" ALTER COLUMN "id" SET NOT NULL;
ALTER TABLE "CatalogItem" ALTER COLUMN "subcategoryId" DROP DEFAULT;

-- Company: uid was added nullable (no default), id was made NOT NULL in Section 4.
-- These are no-ops but kept for safety on fresh DBs.
ALTER TABLE "Company" ALTER COLUMN "uid" DROP DEFAULT;
ALTER TABLE "Company" ALTER COLUMN "id" SET NOT NULL;

-- Opportunity: drop defaults, enforce NOT NULL, drop the old cwDateEntered column
DO $$ BEGIN
  IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'Opportunity' AND column_name = 'cwDateEntered') THEN
    ALTER TABLE "Opportunity" DROP COLUMN "cwDateEntered";
  END IF;
END $$;
ALTER TABLE "Opportunity" ALTER COLUMN "uid" DROP DEFAULT;
ALTER TABLE "Opportunity" ALTER COLUMN "id" SET NOT NULL;
ALTER TABLE "Opportunity" ALTER COLUMN "eneteredBy" DROP DEFAULT;
ALTER TABLE "Opportunity" ALTER COLUMN "typeId" DROP DEFAULT;
ALTER TABLE "Opportunity" ALTER COLUMN "updatedBy" DROP DEFAULT;

-- ProductData: drop the sentinel default on cancelById
ALTER TABLE "ProductData" ALTER COLUMN "cancelById" DROP DEFAULT;

-- ServiceTicket: drop sentinel defaults on FK columns
ALTER TABLE "ServiceTicket" ALTER COLUMN "severityId" DROP DEFAULT;
ALTER TABLE "ServiceTicket" ALTER COLUMN "impactId" DROP DEFAULT;
ALTER TABLE "ServiceTicket" ALTER COLUMN "priorityId" DROP DEFAULT;
ALTER TABLE "ServiceTicket" ALTER COLUMN "sourceId" DROP DEFAULT;
ALTER TABLE "ServiceTicket" ALTER COLUMN "locationId" DROP DEFAULT;

-- TaxCode: drop sentinel default on createdBy
ALTER TABLE "TaxCode" ALTER COLUMN "createdBy" DROP DEFAULT;
