feat: AI Kurzy module, project/service documents, services SQL import
- 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>
This commit is contained in:
230
sql/01_schema_migration.sql
Normal file
230
sql/01_schema_migration.sql
Normal file
@@ -0,0 +1,230 @@
|
||||
-- ============================================================
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user