- Add AI Kurzy module with courses, participants, and registrations management - Add project documents and service documents features - Add service folders for document organization - Add SQL import queries for services from firmy.slovensko.ai - Update todo notifications and group messaging - Various API improvements and bug fixes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
231 lines
8.3 KiB
SQL
231 lines
8.3 KiB
SQL
-- ============================================================
|
|
-- COMPLETE SCHEMA MIGRATION FOR COOLIFY
|
|
-- Run this first to update the database schema
|
|
-- ============================================================
|
|
|
|
-- Create ENUMs for AI Kurzy (if not exist)
|
|
DO $$ BEGIN
|
|
CREATE TYPE "forma_kurzu_enum" AS ENUM('prezencne', 'online', 'hybridne');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE "stav_registracie_enum" AS ENUM('potencialny', 'registrovany', 'potvrdeny', 'absolvoval', 'zruseny');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE "typ_prilohy_enum" AS ENUM('certifikat', 'faktura', 'prihlaska', 'doklad_o_platbe', 'ine');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
-- ============================================================
|
|
-- NEW TABLES
|
|
-- ============================================================
|
|
|
|
-- Chat Groups
|
|
CREATE TABLE IF NOT EXISTS "chat_groups" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"name" text NOT NULL,
|
|
"created_by_id" uuid REFERENCES "users"("id") ON DELETE SET NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Chat Group Members
|
|
CREATE TABLE IF NOT EXISTS "chat_group_members" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"group_id" uuid NOT NULL REFERENCES "chat_groups"("id") ON DELETE CASCADE,
|
|
"user_id" uuid NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
|
|
"joined_at" timestamp DEFAULT now() NOT NULL,
|
|
"last_read_at" timestamp DEFAULT now() NOT NULL,
|
|
CONSTRAINT "chat_group_member_unique" UNIQUE("group_id","user_id")
|
|
);
|
|
|
|
-- Group Messages
|
|
CREATE TABLE IF NOT EXISTS "group_messages" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"group_id" uuid NOT NULL REFERENCES "chat_groups"("id") ON DELETE CASCADE,
|
|
"sender_id" uuid REFERENCES "users"("id") ON DELETE SET NULL,
|
|
"content" text NOT NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Push Subscriptions
|
|
CREATE TABLE IF NOT EXISTS "push_subscriptions" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"user_id" uuid NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
|
|
"endpoint" text NOT NULL,
|
|
"p256dh" text NOT NULL,
|
|
"auth" text NOT NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
CONSTRAINT "push_subscription_endpoint_unique" UNIQUE("user_id","endpoint")
|
|
);
|
|
|
|
-- Email Signatures
|
|
CREATE TABLE IF NOT EXISTS "email_signatures" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"user_id" uuid NOT NULL UNIQUE REFERENCES "users"("id") ON DELETE CASCADE,
|
|
"full_name" text,
|
|
"position" text,
|
|
"phone" text,
|
|
"email" text,
|
|
"company_name" text,
|
|
"website" text,
|
|
"is_enabled" boolean DEFAULT true NOT NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Services
|
|
CREATE TABLE IF NOT EXISTS "services" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"name" text NOT NULL,
|
|
"price" text NOT NULL,
|
|
"description" text,
|
|
"created_by" uuid REFERENCES "users"("id") ON DELETE SET NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Service Folders
|
|
CREATE TABLE IF NOT EXISTS "service_folders" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"name" text NOT NULL,
|
|
"created_by" uuid REFERENCES "users"("id") ON DELETE SET NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Service Documents
|
|
CREATE TABLE IF NOT EXISTS "service_documents" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"folder_id" uuid NOT NULL REFERENCES "service_folders"("id") ON DELETE CASCADE,
|
|
"file_name" text NOT NULL,
|
|
"original_name" text NOT NULL,
|
|
"file_path" text NOT NULL,
|
|
"file_type" text NOT NULL,
|
|
"file_size" integer NOT NULL,
|
|
"description" text,
|
|
"uploaded_by" uuid REFERENCES "users"("id") ON DELETE SET NULL,
|
|
"uploaded_at" timestamp DEFAULT now() NOT NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Company Documents
|
|
CREATE TABLE IF NOT EXISTS "company_documents" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"company_id" uuid NOT NULL REFERENCES "companies"("id") ON DELETE CASCADE,
|
|
"file_name" text NOT NULL,
|
|
"original_name" text NOT NULL,
|
|
"file_path" text NOT NULL,
|
|
"file_type" text NOT NULL,
|
|
"file_size" integer NOT NULL,
|
|
"description" text,
|
|
"uploaded_by" uuid REFERENCES "users"("id") ON DELETE SET NULL,
|
|
"uploaded_at" timestamp DEFAULT now() NOT NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Project Documents
|
|
CREATE TABLE IF NOT EXISTS "project_documents" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"project_id" uuid NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
|
|
"file_name" text NOT NULL,
|
|
"original_name" text NOT NULL,
|
|
"file_path" text NOT NULL,
|
|
"file_type" text NOT NULL,
|
|
"file_size" integer NOT NULL,
|
|
"description" text,
|
|
"uploaded_by" uuid REFERENCES "users"("id") ON DELETE SET NULL,
|
|
"uploaded_at" timestamp DEFAULT now() NOT NULL,
|
|
"created_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- ============================================================
|
|
-- AI KURZY TABLES
|
|
-- ============================================================
|
|
|
|
-- Kurzy (Courses) - without dates (dates are per registration)
|
|
CREATE TABLE IF NOT EXISTS "kurzy" (
|
|
"id" serial PRIMARY KEY NOT NULL,
|
|
"nazov" varchar(255) NOT NULL,
|
|
"typ_kurzu" varchar(100) NOT NULL,
|
|
"popis" text,
|
|
"cena" numeric(10, 2) NOT NULL,
|
|
"max_kapacita" integer,
|
|
"aktivny" boolean DEFAULT true NOT NULL,
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- Ucastnici (Participants)
|
|
CREATE TABLE IF NOT EXISTS "ucastnici" (
|
|
"id" serial PRIMARY KEY NOT NULL,
|
|
"titul" varchar(50),
|
|
"meno" varchar(100) NOT NULL,
|
|
"priezvisko" varchar(100) NOT NULL,
|
|
"email" varchar(255) NOT NULL UNIQUE,
|
|
"telefon" varchar(50),
|
|
"firma" varchar(255),
|
|
"mesto" varchar(100),
|
|
"ulica" varchar(255),
|
|
"psc" varchar(10),
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "ucastnici_email_idx" ON "ucastnici" USING btree ("email");
|
|
|
|
-- Registracie (Registrations) - with dates
|
|
CREATE TABLE IF NOT EXISTS "registracie" (
|
|
"id" serial PRIMARY KEY NOT NULL,
|
|
"kurz_id" integer NOT NULL REFERENCES "kurzy"("id") ON DELETE CASCADE,
|
|
"ucastnik_id" integer NOT NULL REFERENCES "ucastnici"("id") ON DELETE CASCADE,
|
|
"datum_od" date,
|
|
"datum_do" date,
|
|
"forma_kurzu" "forma_kurzu_enum" DEFAULT 'prezencne' NOT NULL,
|
|
"pocet_ucastnikov" integer DEFAULT 1 NOT NULL,
|
|
"faktura_cislo" varchar(100),
|
|
"faktura_vystavena" boolean DEFAULT false NOT NULL,
|
|
"zaplatene" boolean DEFAULT false NOT NULL,
|
|
"stav" "stav_registracie_enum" DEFAULT 'registrovany' NOT NULL,
|
|
"poznamka" text,
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "registracie_kurz_ucastnik_idx" ON "registracie" USING btree ("kurz_id","ucastnik_id");
|
|
|
|
-- Prilohy (Attachments)
|
|
CREATE TABLE IF NOT EXISTS "prilohy" (
|
|
"id" serial PRIMARY KEY NOT NULL,
|
|
"registracia_id" integer NOT NULL REFERENCES "registracie"("id") ON DELETE CASCADE,
|
|
"nazov_suboru" varchar(255) NOT NULL,
|
|
"typ_prilohy" "typ_prilohy_enum" DEFAULT 'ine' NOT NULL,
|
|
"cesta_k_suboru" varchar(500) NOT NULL,
|
|
"mime_type" varchar(100),
|
|
"velkost_suboru" bigint,
|
|
"popis" text,
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
);
|
|
|
|
-- ============================================================
|
|
-- ALTER EXISTING TABLES (add new columns)
|
|
-- ============================================================
|
|
|
|
-- Add completed_notified_at to todos (if not exists)
|
|
DO $$ BEGIN
|
|
ALTER TABLE "todos" ADD COLUMN "completed_notified_at" timestamp;
|
|
EXCEPTION WHEN duplicate_column THEN NULL;
|
|
END $$;
|
|
|
|
-- Make phone nullable in personal_contacts (if needed)
|
|
ALTER TABLE "personal_contacts" ALTER COLUMN "phone" DROP NOT NULL;
|
|
|
|
-- ============================================================
|
|
-- DONE
|
|
-- ============================================================
|
|
SELECT 'Schema migration completed successfully!' as status;
|