Architektur: Craftvia-Domänenmodell, Verträge und Team-Schnitte
- Migration 0002_craftvia_domain: 27 Fachtabellen inkl. RLS (enable_tenant_rls) - TENANT_MODELS (db.ts, backup/topology.ts) um alle Fachmodelle ergänzt - moduleGuard liefert DB-autoritative Rechte; ServiceCtx für Domänen-Services - Verträge: Statusmaschine, Events, Nummernkreise, Sichtbarkeits-Scopes, Job-Queues + Worker, KI-Provider-Interfaces, Sync-Envelope - docs/craftvia/ARCHITEKTUR.md mit Lanes, Ownership und DoD Gate: tsc, lint, build, 22/22 Tests grün. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,926 @@
|
||||
-- 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');
|
||||
Reference in New Issue
Block a user