-- Craftvia domain model (MVP). Generated via prisma migrate diff + RLS block. -- CreateEnum CREATE TYPE "CustomerStatus" AS ENUM ('active', 'inactive', 'provisional', 'merged'); -- CreateEnum CREATE TYPE "SiteStatus" AS ENUM ('active', 'inactive', 'provisional'); -- CreateEnum CREATE TYPE "TeamStatus" AS ENUM ('active', 'inactive'); -- CreateEnum CREATE TYPE "WorkOrderStatus" AS ENUM ('draft', 'review_required', 'planned', 'assigned', 'accepted', 'en_route', 'in_progress', 'paused', 'waiting_material', 'daily_report_created', 'technically_completed', 'signature_pending', 'in_review', 'released_for_billing', 'billed', 'cancelled'); -- CreateEnum CREATE TYPE "WorkOrderPriority" AS ENUM ('low', 'normal', 'high', 'urgent'); -- CreateEnum CREATE TYPE "MaterialUsageStatus" AS ENUM ('fully_used', 'partially_used', 'not_used', 'additional'); -- CreateEnum CREATE TYPE "WorkSessionStatus" AS ENUM ('en_route', 'running', 'paused', 'ended'); -- CreateEnum CREATE TYPE "TimeEntryType" AS ENUM ('travel', 'work', 'break', 'material_procurement', 'return_travel', 'interruption'); -- CreateEnum CREATE TYPE "ActivityNoteKind" AS ENUM ('work_done', 'deviation', 'problem', 'additional_work', 'not_executable', 'follow_up', 'recommendation', 'customer_note', 'general'); -- CreateEnum CREATE TYPE "DocumentCategory" AS ENUM ('order_confirmation', 'technical_drawing', 'floor_plan', 'wiring_diagram', 'assembly_instructions', 'safety_document', 'product_document', 'customer_note', 'work_record', 'daily_report', 'completion_report', 'customer_approval', 'photo', 'voice_note', 'signature', 'other'); -- CreateEnum CREATE TYPE "DocumentVisibility" AS ENUM ('backoffice_only', 'team_lead', 'team', 'customer_report'); -- CreateEnum CREATE TYPE "UploadStatus" AS ENUM ('pending', 'uploaded', 'failed', 'quarantined'); -- CreateEnum CREATE TYPE "PhotoPhase" AS ENUM ('before', 'during', 'after'); -- CreateEnum CREATE TYPE "TranscriptionStatus" AS ENUM ('pending', 'done', 'failed', 'disabled'); -- CreateEnum CREATE TYPE "ReportType" AS ENUM ('daily', 'completion'); -- CreateEnum CREATE TYPE "ReportStatus" AS ENUM ('draft', 'submitted', 'team_approved', 'approved', 'rejected', 'superseded'); -- CreateEnum CREATE TYPE "SignatureOutcome" AS ENUM ('signed', 'customer_absent', 'refused', 'later', 'not_required'); -- CreateEnum CREATE TYPE "ImportStatus" AS ENUM ('uploaded', 'processing', 'review_required', 'confirmed', 'failed', 'discarded'); -- CreateEnum CREATE TYPE "SyncOpStatus" AS ENUM ('applied', 'conflict', 'rejected'); -- CreateTable CREATE TABLE "number_sequences" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "key" TEXT NOT NULL, "prefix" TEXT NOT NULL DEFAULT '', "next_value" INTEGER NOT NULL DEFAULT 1, "padding" INTEGER NOT NULL DEFAULT 5, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "number_sequences_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "order_types" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "key" TEXT NOT NULL, "name" TEXT NOT NULL, "active" BOOLEAN NOT NULL DEFAULT true, "signature_required" BOOLEAN NOT NULL DEFAULT true, "sort_order" INTEGER NOT NULL DEFAULT 0, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "order_types_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "checklist_templates" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "order_type_id" TEXT, "name" TEXT NOT NULL, "active" BOOLEAN NOT NULL DEFAULT true, "items" JSONB NOT NULL DEFAULT '[]', "required_photos" JSONB NOT NULL DEFAULT '[]', "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "checklist_templates_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "customers" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "customer_number" TEXT, "company_name" TEXT, "salutation" TEXT, "first_name" TEXT, "last_name" TEXT, "street" TEXT, "house_number" TEXT, "postal_code" TEXT, "city" TEXT, "country" TEXT NOT NULL DEFAULT 'DE', "phone" TEXT, "mobile" TEXT, "email" TEXT, "notes" TEXT, "billing_notes" TEXT, "status" "CustomerStatus" NOT NULL DEFAULT 'active', "is_provisional" BOOLEAN NOT NULL DEFAULT false, "merged_into_id" TEXT, "created_by_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "customers_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "contacts" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "customer_id" TEXT NOT NULL, "name" TEXT NOT NULL, "role" TEXT, "phone" TEXT, "mobile" TEXT, "email" TEXT, "preferred_channel" TEXT, "notes" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "contacts_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "sites" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "customer_id" TEXT NOT NULL, "name" TEXT NOT NULL, "street" TEXT, "house_number" TEXT, "postal_code" TEXT, "city" TEXT, "country" TEXT NOT NULL DEFAULT 'DE', "contact_id" TEXT, "on_site_contact" TEXT, "phone" TEXT, "access_notes" TEXT, "parking_notes" TEXT, "safety_notes" TEXT, "technical_notes" TEXT, "status" "SiteStatus" NOT NULL DEFAULT 'active', "latitude" DOUBLE PRECISION, "longitude" DOUBLE PRECISION, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "sites_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "teams" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "name" TEXT NOT NULL, "leader_user_id" TEXT, "status" "TeamStatus" NOT NULL DEFAULT 'active', "phone" TEXT, "vehicle" TEXT, "area" TEXT, "notes" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "teams_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "team_members" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "team_id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "valid_from" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "valid_to" TIMESTAMP(3), CONSTRAINT "team_members_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "work_orders" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "number" TEXT NOT NULL, "external_order_number" TEXT, "offer_number" TEXT, "customer_id" TEXT NOT NULL, "site_id" TEXT, "contact_id" TEXT, "order_type_id" TEXT, "priority" "WorkOrderPriority" NOT NULL DEFAULT 'normal', "status" "WorkOrderStatus" NOT NULL DEFAULT 'draft', "title" TEXT NOT NULL, "description" TEXT, "scope" TEXT, "planned_start" TIMESTAMP(3), "planned_end" TIMESTAMP(3), "assigned_team_id" TEXT, "team_lead_user_id" TEXT, "signature_required" BOOLEAN NOT NULL DEFAULT true, "billing_type" TEXT, "internal_notes" TEXT, "technician_notes" TEXT, "is_emergency" BOOLEAN NOT NULL DEFAULT false, "emergency_reason" TEXT, "source_import_id" TEXT, "follow_up_work" TEXT, "version" INTEGER NOT NULL DEFAULT 1, "created_by_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "work_orders_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "work_order_assignees" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "user_id" TEXT NOT NULL, CONSTRAINT "work_order_assignees_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "work_order_status_changes" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "from_status" "WorkOrderStatus", "to_status" "WorkOrderStatus" NOT NULL, "actor_id" TEXT, "reason" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "work_order_status_changes_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "checklist_items" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "key" TEXT NOT NULL, "label" TEXT NOT NULL, "required" BOOLEAN NOT NULL DEFAULT false, "requires_photo" BOOLEAN NOT NULL DEFAULT false, "sort_order" INTEGER NOT NULL DEFAULT 0, "checked" BOOLEAN NOT NULL DEFAULT false, "checked_by_id" TEXT, "checked_at" TIMESTAMP(3), "comment" TEXT, CONSTRAINT "checklist_items_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "photo_requirements" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "key" TEXT NOT NULL, "label" TEXT NOT NULL, "sort_order" INTEGER NOT NULL DEFAULT 0, CONSTRAINT "photo_requirements_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "material_plans" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "name" TEXT NOT NULL, "article_number" TEXT, "planned_quantity" DECIMAL(12,3) NOT NULL, "unit" TEXT NOT NULL, "notes" TEXT, "sort_order" INTEGER NOT NULL DEFAULT 0, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "material_plans_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "material_usages" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "material_plan_id" TEXT, "work_session_id" TEXT, "name" TEXT NOT NULL, "article_number" TEXT, "actual_quantity" DECIMAL(12,3) NOT NULL, "unit" TEXT NOT NULL, "usage_status" "MaterialUsageStatus" NOT NULL, "deviation_reason" TEXT, "notes" TEXT, "photo_id" TEXT, "recorded_by_id" TEXT, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "material_usages_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "work_sessions" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "team_id" TEXT, "status" "WorkSessionStatus" NOT NULL DEFAULT 'running', "started_at" TIMESTAMP(3) NOT NULL, "ended_at" TIMESTAMP(3), "start_lat" DOUBLE PRECISION, "start_lng" DOUBLE PRECISION, "started_offline" BOOLEAN NOT NULL DEFAULT false, "device_info" TEXT, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "work_sessions_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "time_entries" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_session_id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "type" "TimeEntryType" NOT NULL DEFAULT 'work', "started_at" TIMESTAMP(3) NOT NULL, "ended_at" TIMESTAMP(3), "corrected" BOOLEAN NOT NULL DEFAULT false, "correction_reason" TEXT, "corrected_by_id" TEXT, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "time_entries_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "activity_notes" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "author_id" TEXT, "kind" "ActivityNoteKind" NOT NULL DEFAULT 'general', "text" TEXT NOT NULL, "voice_note_id" TEXT, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "activity_notes_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "documents" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "customer_id" TEXT, "site_id" TEXT, "work_order_id" TEXT, "category" "DocumentCategory" NOT NULL, "title" TEXT, "file_name" TEXT NOT NULL, "storage_key" TEXT NOT NULL, "preview_key" TEXT, "mime_type" TEXT NOT NULL, "file_size" INTEGER NOT NULL, "checksum" TEXT NOT NULL, "version" INTEGER NOT NULL DEFAULT 1, "lineage_id" TEXT NOT NULL, "visibility" "DocumentVisibility" NOT NULL DEFAULT 'team', "approval_status" TEXT, "upload_status" "UploadStatus" NOT NULL DEFAULT 'uploaded', "uploaded_by_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "documents_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "photos" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "work_session_id" TEXT, "document_id" TEXT NOT NULL, "checklist_item_id" TEXT, "photo_requirement_id" TEXT, "phase" "PhotoPhase", "comment" TEXT, "taken_at" TIMESTAMP(3) NOT NULL, "latitude" DOUBLE PRECISION, "longitude" DOUBLE PRECISION, "taken_by_id" TEXT, "include_in_report" BOOLEAN NOT NULL DEFAULT true, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "photos_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "voice_notes" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "work_session_id" TEXT, "document_id" TEXT NOT NULL, "duration_seconds" INTEGER, "transcript" TEXT, "transcription_status" "TranscriptionStatus" NOT NULL DEFAULT 'pending', "transcription_model" TEXT, "recorded_by_id" TEXT, "recorded_at" TIMESTAMP(3) NOT NULL, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "voice_notes_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "reports" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "work_order_id" TEXT NOT NULL, "type" "ReportType" NOT NULL, "report_date" DATE NOT NULL, "version" INTEGER NOT NULL DEFAULT 1, "lineage_id" TEXT NOT NULL, "status" "ReportStatus" NOT NULL DEFAULT 'draft', "content" JSONB NOT NULL, "ai_drafted" BOOLEAN NOT NULL DEFAULT false, "ai_generation_id" TEXT, "pdf_document_id" TEXT, "pdf_checksum" TEXT, "created_by_id" TEXT, "submitted_at" TIMESTAMP(3), "team_approved_by_id" TEXT, "team_approved_at" TIMESTAMP(3), "approved_by_id" TEXT, "approved_at" TIMESTAMP(3), "rejection_reason" TEXT, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "reports_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "signatures" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "report_id" TEXT NOT NULL, "outcome" "SignatureOutcome" NOT NULL, "signer_name" TEXT, "signer_role" TEXT, "image_document_id" TEXT, "confirmation_text" TEXT, "reason" TEXT, "signed_at" TIMESTAMP(3) NOT NULL, "captured_by_id" TEXT, "client_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "signatures_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "import_jobs" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "document_id" TEXT NOT NULL, "status" "ImportStatus" NOT NULL DEFAULT 'uploaded', "error_message" TEXT, "extracted_text" TEXT, "extraction" JSONB, "extraction_version" TEXT, "extraction_model" TEXT, "provider" TEXT, "corrections" JSONB, "duplicate_candidates" JSONB, "imported_by_id" TEXT, "confirmed_by_id" TEXT, "confirmed_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "import_jobs_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "notifications" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "type" TEXT NOT NULL, "title" TEXT NOT NULL, "message" TEXT NOT NULL, "entity_type" TEXT, "entity_id" TEXT, "link" TEXT, "read_at" TIMESTAMP(3), "emailed_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "notifications_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "sync_operations" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "client_op_id" TEXT NOT NULL, "op_type" TEXT NOT NULL, "entity_type" TEXT, "entity_id" TEXT, "base_version" INTEGER, "payload" JSONB NOT NULL, "status" "SyncOpStatus" NOT NULL, "result" JSONB, "error_code" TEXT, "client_created_at" TIMESTAMP(3) NOT NULL, "received_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "resolved_by_id" TEXT, "resolved_at" TIMESTAMP(3), CONSTRAINT "sync_operations_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "ai_generations" ( "id" TEXT NOT NULL, "tenant_id" TEXT NOT NULL, "kind" TEXT NOT NULL, "provider" TEXT NOT NULL, "model" TEXT NOT NULL, "entity_type" TEXT, "entity_id" TEXT, "input" JSONB, "output" JSONB, "input_tokens" INTEGER, "output_tokens" INTEGER, "created_by_id" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "ai_generations_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE UNIQUE INDEX "number_sequences_tenant_id_key_key" ON "number_sequences"("tenant_id", "key"); -- CreateIndex CREATE UNIQUE INDEX "order_types_tenant_id_key_key" ON "order_types"("tenant_id", "key"); -- CreateIndex CREATE INDEX "checklist_templates_tenant_id_idx" ON "checklist_templates"("tenant_id"); -- CreateIndex CREATE INDEX "customers_tenant_id_status_idx" ON "customers"("tenant_id", "status"); -- CreateIndex CREATE INDEX "customers_tenant_id_company_name_idx" ON "customers"("tenant_id", "company_name"); -- CreateIndex CREATE INDEX "customers_tenant_id_last_name_idx" ON "customers"("tenant_id", "last_name"); -- CreateIndex CREATE UNIQUE INDEX "customers_tenant_id_customer_number_key" ON "customers"("tenant_id", "customer_number"); -- CreateIndex CREATE INDEX "contacts_tenant_id_customer_id_idx" ON "contacts"("tenant_id", "customer_id"); -- CreateIndex CREATE INDEX "sites_tenant_id_customer_id_idx" ON "sites"("tenant_id", "customer_id"); -- CreateIndex CREATE UNIQUE INDEX "teams_tenant_id_name_key" ON "teams"("tenant_id", "name"); -- CreateIndex CREATE INDEX "team_members_tenant_id_user_id_idx" ON "team_members"("tenant_id", "user_id"); -- CreateIndex CREATE INDEX "team_members_team_id_idx" ON "team_members"("team_id"); -- CreateIndex CREATE UNIQUE INDEX "work_orders_source_import_id_key" ON "work_orders"("source_import_id"); -- CreateIndex CREATE INDEX "work_orders_tenant_id_status_idx" ON "work_orders"("tenant_id", "status"); -- CreateIndex CREATE INDEX "work_orders_tenant_id_assigned_team_id_status_idx" ON "work_orders"("tenant_id", "assigned_team_id", "status"); -- CreateIndex CREATE INDEX "work_orders_tenant_id_planned_start_idx" ON "work_orders"("tenant_id", "planned_start"); -- CreateIndex CREATE INDEX "work_orders_tenant_id_customer_id_idx" ON "work_orders"("tenant_id", "customer_id"); -- CreateIndex CREATE INDEX "work_orders_tenant_id_site_id_idx" ON "work_orders"("tenant_id", "site_id"); -- CreateIndex CREATE UNIQUE INDEX "work_orders_tenant_id_number_key" ON "work_orders"("tenant_id", "number"); -- CreateIndex CREATE INDEX "work_order_assignees_tenant_id_user_id_idx" ON "work_order_assignees"("tenant_id", "user_id"); -- CreateIndex CREATE UNIQUE INDEX "work_order_assignees_work_order_id_user_id_key" ON "work_order_assignees"("work_order_id", "user_id"); -- CreateIndex CREATE INDEX "work_order_status_changes_tenant_id_work_order_id_idx" ON "work_order_status_changes"("tenant_id", "work_order_id"); -- CreateIndex CREATE INDEX "checklist_items_tenant_id_work_order_id_idx" ON "checklist_items"("tenant_id", "work_order_id"); -- CreateIndex CREATE INDEX "photo_requirements_tenant_id_idx" ON "photo_requirements"("tenant_id"); -- CreateIndex CREATE UNIQUE INDEX "photo_requirements_work_order_id_key_key" ON "photo_requirements"("work_order_id", "key"); -- CreateIndex CREATE INDEX "material_plans_tenant_id_work_order_id_idx" ON "material_plans"("tenant_id", "work_order_id"); -- CreateIndex CREATE UNIQUE INDEX "material_usages_client_id_key" ON "material_usages"("client_id"); -- CreateIndex CREATE INDEX "material_usages_tenant_id_work_order_id_idx" ON "material_usages"("tenant_id", "work_order_id"); -- CreateIndex CREATE UNIQUE INDEX "work_sessions_client_id_key" ON "work_sessions"("client_id"); -- CreateIndex CREATE INDEX "work_sessions_tenant_id_work_order_id_idx" ON "work_sessions"("tenant_id", "work_order_id"); -- CreateIndex CREATE INDEX "work_sessions_tenant_id_user_id_status_idx" ON "work_sessions"("tenant_id", "user_id", "status"); -- CreateIndex CREATE UNIQUE INDEX "time_entries_client_id_key" ON "time_entries"("client_id"); -- CreateIndex CREATE INDEX "time_entries_tenant_id_work_session_id_idx" ON "time_entries"("tenant_id", "work_session_id"); -- CreateIndex CREATE INDEX "time_entries_tenant_id_user_id_started_at_idx" ON "time_entries"("tenant_id", "user_id", "started_at"); -- CreateIndex CREATE UNIQUE INDEX "activity_notes_voice_note_id_key" ON "activity_notes"("voice_note_id"); -- CreateIndex CREATE UNIQUE INDEX "activity_notes_client_id_key" ON "activity_notes"("client_id"); -- CreateIndex CREATE INDEX "activity_notes_tenant_id_work_order_id_idx" ON "activity_notes"("tenant_id", "work_order_id"); -- CreateIndex CREATE INDEX "documents_tenant_id_work_order_id_idx" ON "documents"("tenant_id", "work_order_id"); -- CreateIndex CREATE INDEX "documents_tenant_id_site_id_idx" ON "documents"("tenant_id", "site_id"); -- CreateIndex CREATE INDEX "documents_tenant_id_customer_id_idx" ON "documents"("tenant_id", "customer_id"); -- CreateIndex CREATE UNIQUE INDEX "documents_lineage_id_version_key" ON "documents"("lineage_id", "version"); -- CreateIndex CREATE UNIQUE INDEX "photos_document_id_key" ON "photos"("document_id"); -- CreateIndex CREATE UNIQUE INDEX "photos_client_id_key" ON "photos"("client_id"); -- CreateIndex CREATE INDEX "photos_tenant_id_work_order_id_idx" ON "photos"("tenant_id", "work_order_id"); -- CreateIndex CREATE UNIQUE INDEX "voice_notes_document_id_key" ON "voice_notes"("document_id"); -- CreateIndex CREATE UNIQUE INDEX "voice_notes_client_id_key" ON "voice_notes"("client_id"); -- CreateIndex CREATE INDEX "voice_notes_tenant_id_work_order_id_idx" ON "voice_notes"("tenant_id", "work_order_id"); -- CreateIndex CREATE UNIQUE INDEX "reports_pdf_document_id_key" ON "reports"("pdf_document_id"); -- CreateIndex CREATE UNIQUE INDEX "reports_client_id_key" ON "reports"("client_id"); -- CreateIndex CREATE INDEX "reports_tenant_id_work_order_id_idx" ON "reports"("tenant_id", "work_order_id"); -- CreateIndex CREATE INDEX "reports_tenant_id_status_idx" ON "reports"("tenant_id", "status"); -- CreateIndex CREATE UNIQUE INDEX "reports_lineage_id_version_key" ON "reports"("lineage_id", "version"); -- CreateIndex CREATE UNIQUE INDEX "signatures_report_id_key" ON "signatures"("report_id"); -- CreateIndex CREATE UNIQUE INDEX "signatures_image_document_id_key" ON "signatures"("image_document_id"); -- CreateIndex CREATE UNIQUE INDEX "signatures_client_id_key" ON "signatures"("client_id"); -- CreateIndex CREATE INDEX "signatures_tenant_id_idx" ON "signatures"("tenant_id"); -- CreateIndex CREATE UNIQUE INDEX "import_jobs_document_id_key" ON "import_jobs"("document_id"); -- CreateIndex CREATE INDEX "import_jobs_tenant_id_status_idx" ON "import_jobs"("tenant_id", "status"); -- CreateIndex CREATE INDEX "notifications_tenant_id_user_id_read_at_idx" ON "notifications"("tenant_id", "user_id", "read_at"); -- CreateIndex CREATE INDEX "sync_operations_tenant_id_status_idx" ON "sync_operations"("tenant_id", "status"); -- CreateIndex CREATE UNIQUE INDEX "sync_operations_tenant_id_client_op_id_key" ON "sync_operations"("tenant_id", "client_op_id"); -- CreateIndex CREATE INDEX "ai_generations_tenant_id_entity_type_entity_id_idx" ON "ai_generations"("tenant_id", "entity_type", "entity_id"); -- AddForeignKey ALTER TABLE "checklist_templates" ADD CONSTRAINT "checklist_templates_order_type_id_fkey" FOREIGN KEY ("order_type_id") REFERENCES "order_types"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "contacts" ADD CONSTRAINT "contacts_customer_id_fkey" FOREIGN KEY ("customer_id") REFERENCES "customers"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "sites" ADD CONSTRAINT "sites_customer_id_fkey" FOREIGN KEY ("customer_id") REFERENCES "customers"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "sites" ADD CONSTRAINT "sites_contact_id_fkey" FOREIGN KEY ("contact_id") REFERENCES "contacts"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "teams" ADD CONSTRAINT "teams_leader_user_id_fkey" FOREIGN KEY ("leader_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "team_members" ADD CONSTRAINT "team_members_team_id_fkey" FOREIGN KEY ("team_id") REFERENCES "teams"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "team_members" ADD CONSTRAINT "team_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_customer_id_fkey" FOREIGN KEY ("customer_id") REFERENCES "customers"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_site_id_fkey" FOREIGN KEY ("site_id") REFERENCES "sites"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_contact_id_fkey" FOREIGN KEY ("contact_id") REFERENCES "contacts"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_order_type_id_fkey" FOREIGN KEY ("order_type_id") REFERENCES "order_types"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_assigned_team_id_fkey" FOREIGN KEY ("assigned_team_id") REFERENCES "teams"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_team_lead_user_id_fkey" FOREIGN KEY ("team_lead_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_source_import_id_fkey" FOREIGN KEY ("source_import_id") REFERENCES "import_jobs"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_order_assignees" ADD CONSTRAINT "work_order_assignees_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_order_assignees" ADD CONSTRAINT "work_order_assignees_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_order_status_changes" ADD CONSTRAINT "work_order_status_changes_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "checklist_items" ADD CONSTRAINT "checklist_items_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "photo_requirements" ADD CONSTRAINT "photo_requirements_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "material_plans" ADD CONSTRAINT "material_plans_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "material_usages" ADD CONSTRAINT "material_usages_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "material_usages" ADD CONSTRAINT "material_usages_material_plan_id_fkey" FOREIGN KEY ("material_plan_id") REFERENCES "material_plans"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "material_usages" ADD CONSTRAINT "material_usages_work_session_id_fkey" FOREIGN KEY ("work_session_id") REFERENCES "work_sessions"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_sessions" ADD CONSTRAINT "work_sessions_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "work_sessions" ADD CONSTRAINT "work_sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "time_entries" ADD CONSTRAINT "time_entries_work_session_id_fkey" FOREIGN KEY ("work_session_id") REFERENCES "work_sessions"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "activity_notes" ADD CONSTRAINT "activity_notes_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "activity_notes" ADD CONSTRAINT "activity_notes_voice_note_id_fkey" FOREIGN KEY ("voice_note_id") REFERENCES "voice_notes"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "documents" ADD CONSTRAINT "documents_customer_id_fkey" FOREIGN KEY ("customer_id") REFERENCES "customers"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "documents" ADD CONSTRAINT "documents_site_id_fkey" FOREIGN KEY ("site_id") REFERENCES "sites"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "documents" ADD CONSTRAINT "documents_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "photos" ADD CONSTRAINT "photos_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "photos" ADD CONSTRAINT "photos_checklist_item_id_fkey" FOREIGN KEY ("checklist_item_id") REFERENCES "checklist_items"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "photos" ADD CONSTRAINT "photos_photo_requirement_id_fkey" FOREIGN KEY ("photo_requirement_id") REFERENCES "photo_requirements"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "voice_notes" ADD CONSTRAINT "voice_notes_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "reports" ADD CONSTRAINT "reports_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "signatures" ADD CONSTRAINT "signatures_report_id_fkey" FOREIGN KEY ("report_id") REFERENCES "reports"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "notifications" ADD CONSTRAINT "notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- Row Level Security for all Craftvia tenant tables (mirror of TENANT_MODELS) SELECT enable_tenant_rls('number_sequences'); SELECT enable_tenant_rls('order_types'); SELECT enable_tenant_rls('checklist_templates'); SELECT enable_tenant_rls('customers'); SELECT enable_tenant_rls('contacts'); SELECT enable_tenant_rls('sites'); SELECT enable_tenant_rls('teams'); SELECT enable_tenant_rls('team_members'); SELECT enable_tenant_rls('work_orders'); SELECT enable_tenant_rls('work_order_assignees'); SELECT enable_tenant_rls('work_order_status_changes'); SELECT enable_tenant_rls('checklist_items'); SELECT enable_tenant_rls('photo_requirements'); SELECT enable_tenant_rls('material_plans'); SELECT enable_tenant_rls('material_usages'); SELECT enable_tenant_rls('work_sessions'); SELECT enable_tenant_rls('time_entries'); SELECT enable_tenant_rls('activity_notes'); SELECT enable_tenant_rls('documents'); SELECT enable_tenant_rls('photos'); SELECT enable_tenant_rls('voice_notes'); SELECT enable_tenant_rls('reports'); SELECT enable_tenant_rls('signatures'); SELECT enable_tenant_rls('import_jobs'); SELECT enable_tenant_rls('notifications'); SELECT enable_tenant_rls('sync_operations'); SELECT enable_tenant_rls('ai_generations');