commit
This commit is contained in:
46
drizzle/0000_married_ink.sql
Normal file
46
drizzle/0000_married_ink.sql
Normal file
@@ -0,0 +1,46 @@
|
||||
CREATE TABLE "memberships" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"role" text DEFAULT 'owner' NOT NULL,
|
||||
"permissions" text[] DEFAULT '{}' NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "organizations" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"slug" text NOT NULL,
|
||||
"image_url" text,
|
||||
"plan" text DEFAULT 'free' NOT NULL,
|
||||
"created_by" text NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "products" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "products_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"category" text NOT NULL,
|
||||
"description" text NOT NULL,
|
||||
"photo_url" text NOT NULL,
|
||||
"price" double precision NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "users" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"email" text NOT NULL,
|
||||
"password_hash" text NOT NULL,
|
||||
"image" text,
|
||||
"active_organization_id" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "organizations_slug_idx" ON "organizations" USING btree ("slug");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "users_email_idx" ON "users" USING btree ("email");
|
||||
133
drizzle/0001_fancy_wolfpack.sql
Normal file
133
drizzle/0001_fancy_wolfpack.sql
Normal file
@@ -0,0 +1,133 @@
|
||||
CREATE TYPE "public"."approval_status" AS ENUM('pending', 'approved', 'rejected', 'needs_revision');--> statement-breakpoint
|
||||
CREATE TYPE "public"."membership_role" AS ENUM('owner', 'admin', 'member');--> statement-breakpoint
|
||||
CREATE TYPE "public"."training_type" AS ENUM('online', 'onsite', 'internal', 'external');--> statement-breakpoint
|
||||
CREATE TABLE "certificates" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "certificates_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"training_record_id" integer NOT NULL,
|
||||
"file_name" text NOT NULL,
|
||||
"file_type" text NOT NULL,
|
||||
"file_size" integer NOT NULL,
|
||||
"storage_key" text NOT NULL,
|
||||
"file_url" text,
|
||||
"uploaded_by" text NOT NULL,
|
||||
"uploaded_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "courses" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "courses_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"category" text NOT NULL,
|
||||
"organizer" text,
|
||||
"standard_hours" double precision DEFAULT 0 NOT NULL,
|
||||
"certificate_validity_months" integer,
|
||||
"is_required" boolean DEFAULT false NOT NULL,
|
||||
"description" text,
|
||||
"is_active" 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
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "departments" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "departments_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"code" text,
|
||||
"name" text NOT NULL,
|
||||
"description" text,
|
||||
"is_active" 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
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "employees" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "employees_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"employee_code" text NOT NULL,
|
||||
"full_name" text NOT NULL,
|
||||
"email" text,
|
||||
"company" text,
|
||||
"department_id" integer,
|
||||
"position_id" integer,
|
||||
"hired_at" timestamp with time zone,
|
||||
"is_active" 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
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "positions" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "positions_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"code" text,
|
||||
"name" text NOT NULL,
|
||||
"description" text,
|
||||
"is_active" 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
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "training_matrices" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "training_matrices_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"department_id" integer,
|
||||
"position_id" integer,
|
||||
"course_id" integer NOT NULL,
|
||||
"is_required" boolean DEFAULT true NOT NULL,
|
||||
"renewal_period_months" integer,
|
||||
"note" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "training_records" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "training_records_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"employee_id" integer NOT NULL,
|
||||
"course_id" integer NOT NULL,
|
||||
"training_date" timestamp with time zone NOT NULL,
|
||||
"training_type" "training_type" NOT NULL,
|
||||
"hours" double precision NOT NULL,
|
||||
"organizer" text,
|
||||
"note" text,
|
||||
"approval_status" "approval_status" DEFAULT 'pending' NOT NULL,
|
||||
"reviewer_note" text,
|
||||
"reviewed_by" text,
|
||||
"reviewed_at" timestamp with time zone,
|
||||
"created_by" text NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "memberships" ALTER COLUMN "role" SET DEFAULT 'owner'::"public"."membership_role";--> statement-breakpoint
|
||||
ALTER TABLE "memberships" ALTER COLUMN "role" SET DATA TYPE "public"."membership_role" USING "role"::"public"."membership_role";--> statement-breakpoint
|
||||
ALTER TABLE "certificates" ADD CONSTRAINT "certificates_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "certificates" ADD CONSTRAINT "certificates_training_record_id_training_records_id_fk" FOREIGN KEY ("training_record_id") REFERENCES "public"."training_records"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "certificates" ADD CONSTRAINT "certificates_uploaded_by_users_id_fk" FOREIGN KEY ("uploaded_by") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "courses" ADD CONSTRAINT "courses_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "departments" ADD CONSTRAINT "departments_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD CONSTRAINT "employees_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD CONSTRAINT "employees_department_id_departments_id_fk" FOREIGN KEY ("department_id") REFERENCES "public"."departments"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD CONSTRAINT "employees_position_id_positions_id_fk" FOREIGN KEY ("position_id") REFERENCES "public"."positions"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "positions" ADD CONSTRAINT "positions_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_matrices" ADD CONSTRAINT "training_matrices_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_matrices" ADD CONSTRAINT "training_matrices_department_id_departments_id_fk" FOREIGN KEY ("department_id") REFERENCES "public"."departments"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_matrices" ADD CONSTRAINT "training_matrices_position_id_positions_id_fk" FOREIGN KEY ("position_id") REFERENCES "public"."positions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_matrices" ADD CONSTRAINT "training_matrices_course_id_courses_id_fk" FOREIGN KEY ("course_id") REFERENCES "public"."courses"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_employee_id_employees_id_fk" FOREIGN KEY ("employee_id") REFERENCES "public"."employees"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_course_id_courses_id_fk" FOREIGN KEY ("course_id") REFERENCES "public"."courses"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_reviewed_by_users_id_fk" FOREIGN KEY ("reviewed_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "courses_org_name_idx" ON "courses" USING btree ("organization_id","name");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "departments_org_code_idx" ON "departments" USING btree ("organization_id","code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "departments_org_name_idx" ON "departments" USING btree ("organization_id","name");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "employees_org_employee_code_idx" ON "employees" USING btree ("organization_id","employee_code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "positions_org_code_idx" ON "positions" USING btree ("organization_id","code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "positions_org_name_idx" ON "positions" USING btree ("organization_id","name");--> statement-breakpoint
|
||||
ALTER TABLE "memberships" ADD CONSTRAINT "memberships_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "memberships" ADD CONSTRAINT "memberships_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "organizations" ADD CONSTRAINT "organizations_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "products" ADD CONSTRAINT "products_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "memberships_user_org_idx" ON "memberships" USING btree ("user_id","organization_id");
|
||||
17
drizzle/0002_unusual_whirlwind.sql
Normal file
17
drizzle/0002_unusual_whirlwind.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
CREATE TYPE "public"."system_role" AS ENUM('standard', 'super_admin');--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "phone" text;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "system_role" "system_role" DEFAULT 'standard' NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "is_active" boolean DEFAULT true NOT NULL;--> statement-breakpoint
|
||||
UPDATE "users"
|
||||
SET "system_role" = 'super_admin'
|
||||
WHERE "id" = (
|
||||
SELECT "id"
|
||||
FROM "users"
|
||||
ORDER BY "created_at" ASC
|
||||
LIMIT 1
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM "users"
|
||||
WHERE "system_role" = 'super_admin'
|
||||
);
|
||||
103
drizzle/0003_unify_users_training.sql
Normal file
103
drizzle/0003_unify_users_training.sql
Normal file
@@ -0,0 +1,103 @@
|
||||
ALTER TABLE "users" ADD COLUMN "employee_code" text;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "department_id" integer;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "position_id" integer;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "company_name" text;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "hired_at" timestamp with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD COLUMN "user_id" text;--> statement-breakpoint
|
||||
|
||||
UPDATE "users" AS "u"
|
||||
SET
|
||||
"employee_code" = "e"."employee_code",
|
||||
"department_id" = "e"."department_id",
|
||||
"position_id" = "e"."position_id",
|
||||
"company_name" = COALESCE("e"."company", "o"."name"),
|
||||
"hired_at" = "e"."hired_at",
|
||||
"updated_at" = NOW()
|
||||
FROM "employees" AS "e"
|
||||
INNER JOIN "organizations" AS "o" ON "o"."id" = "e"."organization_id"
|
||||
WHERE "u"."email" IS NOT NULL
|
||||
AND "e"."email" IS NOT NULL
|
||||
AND LOWER("u"."email") = LOWER("e"."email");--> statement-breakpoint
|
||||
|
||||
INSERT INTO "users" (
|
||||
"id",
|
||||
"name",
|
||||
"email",
|
||||
"password_hash",
|
||||
"system_role",
|
||||
"is_active",
|
||||
"employee_code",
|
||||
"department_id",
|
||||
"position_id",
|
||||
"company_name",
|
||||
"hired_at",
|
||||
"active_organization_id"
|
||||
)
|
||||
SELECT
|
||||
CONCAT('legacy-employee-', "e"."id", '-', "e"."organization_id") AS "id",
|
||||
"e"."full_name",
|
||||
COALESCE(LOWER("e"."email"), CONCAT('employee-', "e"."id", '@training-system.local')),
|
||||
'$2b$10$sl8.hKi0l/KXnouzGgiRvOpNgZ9TT8RFvdPjQbgxCV5WirdWv1uBq',
|
||||
'standard',
|
||||
false,
|
||||
"e"."employee_code",
|
||||
"e"."department_id",
|
||||
"e"."position_id",
|
||||
COALESCE("e"."company", "o"."name"),
|
||||
"e"."hired_at",
|
||||
"e"."organization_id"
|
||||
FROM "employees" AS "e"
|
||||
INNER JOIN "organizations" AS "o" ON "o"."id" = "e"."organization_id"
|
||||
LEFT JOIN "users" AS "u"
|
||||
ON (
|
||||
("e"."email" IS NOT NULL AND LOWER("u"."email") = LOWER("e"."email"))
|
||||
OR ("u"."employee_code" IS NOT NULL AND "u"."employee_code" = "e"."employee_code")
|
||||
)
|
||||
WHERE "u"."id" IS NULL;--> statement-breakpoint
|
||||
|
||||
INSERT INTO "memberships" (
|
||||
"id",
|
||||
"user_id",
|
||||
"organization_id",
|
||||
"role",
|
||||
"permissions"
|
||||
)
|
||||
SELECT
|
||||
CONCAT('legacy-membership-', "e"."id", '-', "e"."organization_id"),
|
||||
CONCAT('legacy-employee-', "e"."id", '-', "e"."organization_id"),
|
||||
"e"."organization_id",
|
||||
'member',
|
||||
ARRAY['products:read']::text[]
|
||||
FROM "employees" AS "e"
|
||||
LEFT JOIN "memberships" AS "m"
|
||||
ON "m"."user_id" = CONCAT('legacy-employee-', "e"."id", '-', "e"."organization_id")
|
||||
AND "m"."organization_id" = "e"."organization_id"
|
||||
WHERE "m"."id" IS NULL
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM "users" AS "u"
|
||||
WHERE "u"."id" = CONCAT('legacy-employee-', "e"."id", '-', "e"."organization_id")
|
||||
);--> statement-breakpoint
|
||||
|
||||
UPDATE "training_records" AS "tr"
|
||||
SET "user_id" = COALESCE(
|
||||
(
|
||||
SELECT "u"."id"
|
||||
FROM "users" AS "u"
|
||||
INNER JOIN "employees" AS "e" ON LOWER("u"."email") = LOWER("e"."email")
|
||||
WHERE "e"."id" = "tr"."employee_id"
|
||||
LIMIT 1
|
||||
),
|
||||
CONCAT(
|
||||
'legacy-employee-',
|
||||
"tr"."employee_id",
|
||||
'-',
|
||||
"tr"."organization_id"
|
||||
)
|
||||
)
|
||||
WHERE "tr"."user_id" IS NULL;--> statement-breakpoint
|
||||
|
||||
ALTER TABLE "training_records" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" DROP CONSTRAINT "training_records_employee_id_employees_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_employee_id_employees_id_fk" FOREIGN KEY ("employee_id") REFERENCES "public"."employees"("id") ON DELETE set null ON UPDATE no action;
|
||||
15
drizzle/0004_free_text_training_courses.sql
Normal file
15
drizzle/0004_free_text_training_courses.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
ALTER TABLE "training_records" ADD COLUMN "course_name" text;
|
||||
--> statement-breakpoint
|
||||
UPDATE "training_records" AS "tr"
|
||||
SET "course_name" = "c"."name"
|
||||
FROM "courses" AS "c"
|
||||
WHERE "tr"."course_id" = "c"."id"
|
||||
AND "tr"."course_name" IS NULL;
|
||||
--> statement-breakpoint
|
||||
UPDATE "training_records"
|
||||
SET "course_name" = 'External course'
|
||||
WHERE "course_name" IS NULL;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ALTER COLUMN "course_name" SET NOT NULL;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ALTER COLUMN "course_id" DROP NOT NULL;
|
||||
1
drizzle/0005_training_record_employee_id_nullable.sql
Normal file
1
drizzle/0005_training_record_employee_id_nullable.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "training_records" ALTER COLUMN "employee_id" DROP NOT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "training_records" ALTER COLUMN "employee_id" DROP NOT NULL;
|
||||
102
drizzle/0007_sticky_korath.sql
Normal file
102
drizzle/0007_sticky_korath.sql
Normal file
@@ -0,0 +1,102 @@
|
||||
CREATE TYPE "public"."announcement_status" AS ENUM('draft', 'published', 'archived');--> statement-breakpoint
|
||||
CREATE TYPE "public"."import_status" AS ENUM('processing', 'completed', 'failed');--> statement-breakpoint
|
||||
CREATE TYPE "public"."notification_type" AS ENUM('approved', 'rejected', 'announcement', 'reminder');--> statement-breakpoint
|
||||
CREATE TYPE "public"."training_category" AS ENUM('K', 'S', 'A');--> statement-breakpoint
|
||||
CREATE TABLE "announcements" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "announcements_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"title" text NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"attachment_file_name" text,
|
||||
"attachment_file_type" text,
|
||||
"attachment_file_size" integer,
|
||||
"attachment_storage_key" text,
|
||||
"attachment_file_url" text,
|
||||
"start_date" timestamp with time zone NOT NULL,
|
||||
"end_date" timestamp with time zone,
|
||||
"is_pin" boolean DEFAULT false NOT NULL,
|
||||
"status" "announcement_status" DEFAULT 'draft' NOT NULL,
|
||||
"created_by" text NOT NULL,
|
||||
"updated_by" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "audit_logs" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "audit_logs_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text,
|
||||
"user_id" text,
|
||||
"module_name" text NOT NULL,
|
||||
"action" text NOT NULL,
|
||||
"entity_name" text,
|
||||
"entity_id" text,
|
||||
"old_value" jsonb,
|
||||
"new_value" jsonb,
|
||||
"ip_address" text,
|
||||
"user_agent" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "import_jobs" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "import_jobs_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"import_type" text NOT NULL,
|
||||
"file_name" text NOT NULL,
|
||||
"total_rows" integer DEFAULT 0 NOT NULL,
|
||||
"success_rows" integer DEFAULT 0 NOT NULL,
|
||||
"failed_rows" integer DEFAULT 0 NOT NULL,
|
||||
"status" "import_status" DEFAULT 'processing' NOT NULL,
|
||||
"error_message" text,
|
||||
"created_by" text NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "notifications" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "notifications_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"title" text NOT NULL,
|
||||
"message" text NOT NULL,
|
||||
"type" "notification_type" NOT NULL,
|
||||
"reference_type" text,
|
||||
"reference_id" text,
|
||||
"is_read" boolean DEFAULT false NOT NULL,
|
||||
"read_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "training_policies" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "training_policies_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"year" integer NOT NULL,
|
||||
"total_hours" double precision DEFAULT 30 NOT NULL,
|
||||
"k_hours" double precision DEFAULT 12 NOT NULL,
|
||||
"s_hours" double precision DEFAULT 12 NOT NULL,
|
||||
"a_hours" double precision DEFAULT 6 NOT NULL,
|
||||
"is_active" 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
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "password_hash" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "courses" ADD COLUMN "course_code" text;--> statement-breakpoint
|
||||
ALTER TABLE "courses" ADD COLUMN "certificate_required" boolean DEFAULT true NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "courses" ADD COLUMN "training_cost" double precision;--> statement-breakpoint
|
||||
ALTER TABLE "departments" ADD COLUMN "pending_master_review" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "pending_master_review" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "organizations" ADD COLUMN "pending_master_review" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "positions" ADD COLUMN "pending_master_review" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD COLUMN "approved_hours" double precision;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD COLUMN "category" "training_category";--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD COLUMN "reject_reason" text;--> statement-breakpoint
|
||||
ALTER TABLE "announcements" ADD CONSTRAINT "announcements_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "announcements" ADD CONSTRAINT "announcements_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "announcements" ADD CONSTRAINT "announcements_updated_by_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "import_jobs" ADD CONSTRAINT "import_jobs_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "import_jobs" ADD CONSTRAINT "import_jobs_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "notifications" ADD CONSTRAINT "notifications_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "notifications" ADD CONSTRAINT "notifications_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_policies" ADD CONSTRAINT "training_policies_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "training_policies_org_year_idx" ON "training_policies" USING btree ("organization_id","year");
|
||||
2
drizzle/0008_nosy_robin_chapel.sql
Normal file
2
drizzle/0008_nosy_robin_chapel.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "users" ADD COLUMN "username" text;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "users_username_idx" ON "users" USING btree ("username");
|
||||
51
drizzle/0009_lean_hobgoblin.sql
Normal file
51
drizzle/0009_lean_hobgoblin.sql
Normal file
@@ -0,0 +1,51 @@
|
||||
ALTER TABLE "employees" ADD COLUMN "prefix" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "first_name_th" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "last_name_th" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "first_name_en" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "last_name_en" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "display_name" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "phone" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "company_name" text;--> statement-breakpoint
|
||||
ALTER TABLE "employees" ADD COLUMN "status" text DEFAULT 'active' NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "provider" text DEFAULT 'credentials' NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "provider_user_id" text;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "employee_id" integer;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "last_login_at" timestamp with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "employee_training_targets" ADD COLUMN "employee_id" integer;--> statement-breakpoint
|
||||
ALTER TABLE "employee_training_targets" ADD CONSTRAINT "employee_training_targets_employee_id_employees_id_fk" FOREIGN KEY ("employee_id") REFERENCES "public"."employees"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD CONSTRAINT "users_employee_id_employees_id_fk" FOREIGN KEY ("employee_id") REFERENCES "public"."employees"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "users_provider_user_id_idx" ON "users" USING btree ("provider","provider_user_id");--> statement-breakpoint
|
||||
|
||||
UPDATE "employees"
|
||||
SET
|
||||
"display_name" = COALESCE("display_name", "full_name"),
|
||||
"company_name" = COALESCE("company_name", "company"),
|
||||
"status" = CASE WHEN "is_active" = true THEN 'active' ELSE 'inactive' END;--> statement-breakpoint
|
||||
|
||||
UPDATE "users"
|
||||
SET "provider" = COALESCE("provider", 'credentials')
|
||||
WHERE "provider" IS NULL;--> statement-breakpoint
|
||||
|
||||
UPDATE "users" u
|
||||
SET "employee_id" = e."id"
|
||||
FROM "memberships" m
|
||||
INNER JOIN "employees" e
|
||||
ON e."organization_id" = m."organization_id"
|
||||
AND e."employee_code" = u."employee_code"
|
||||
WHERE m."user_id" = u."id"
|
||||
AND u."employee_code" IS NOT NULL
|
||||
AND (u."employee_id" IS NULL OR u."employee_id" <> e."id");--> statement-breakpoint
|
||||
|
||||
UPDATE "training_records" tr
|
||||
SET "employee_id" = u."employee_id"
|
||||
FROM "users" u
|
||||
WHERE tr."user_id" = u."id"
|
||||
AND tr."employee_id" IS NULL
|
||||
AND u."employee_id" IS NOT NULL;--> statement-breakpoint
|
||||
|
||||
UPDATE "employee_training_targets" ett
|
||||
SET "employee_id" = u."employee_id"
|
||||
FROM "users" u
|
||||
WHERE ett."user_id" = u."id"
|
||||
AND ett."employee_id" IS NULL
|
||||
AND u."employee_id" IS NOT NULL;
|
||||
58
drizzle/0010_romantic_marauders.sql
Normal file
58
drizzle/0010_romantic_marauders.sql
Normal file
@@ -0,0 +1,58 @@
|
||||
CREATE TABLE "user_employee_maps" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "user_employee_maps_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"employee_id" integer NOT NULL,
|
||||
"provider" text,
|
||||
"provider_user_id" text,
|
||||
"source" text DEFAULT 'manual' NOT NULL,
|
||||
"is_primary" boolean DEFAULT true NOT NULL,
|
||||
"linked_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "training_records" DROP CONSTRAINT "training_records_user_id_users_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "employee_training_targets" ALTER COLUMN "user_id" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ALTER COLUMN "user_id" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD COLUMN "submitted_by_user_id" text;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD COLUMN "reviewed_by_user_id" text;--> statement-breakpoint
|
||||
ALTER TABLE "user_employee_maps" ADD CONSTRAINT "user_employee_maps_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_employee_maps" ADD CONSTRAINT "user_employee_maps_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_employee_maps" ADD CONSTRAINT "user_employee_maps_employee_id_employees_id_fk" FOREIGN KEY ("employee_id") REFERENCES "public"."employees"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "user_employee_maps_org_user_employee_idx" ON "user_employee_maps" USING btree ("organization_id","user_id","employee_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "employee_training_targets_org_employee_year_idx" ON "employee_training_targets" USING btree ("organization_id","employee_id","year");--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_submitted_by_user_id_users_id_fk" FOREIGN KEY ("submitted_by_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_reviewed_by_user_id_users_id_fk" FOREIGN KEY ("reviewed_by_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "training_records" ADD CONSTRAINT "training_records_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
|
||||
INSERT INTO "user_employee_maps" (
|
||||
"organization_id",
|
||||
"user_id",
|
||||
"employee_id",
|
||||
"provider",
|
||||
"provider_user_id",
|
||||
"source",
|
||||
"is_primary"
|
||||
)
|
||||
SELECT
|
||||
m."organization_id",
|
||||
u."id",
|
||||
u."employee_id",
|
||||
u."provider",
|
||||
u."provider_user_id",
|
||||
'legacy_backfill',
|
||||
true
|
||||
FROM "users" u
|
||||
INNER JOIN "memberships" m ON m."user_id" = u."id"
|
||||
WHERE u."employee_id" IS NOT NULL
|
||||
ON CONFLICT ("organization_id","user_id","employee_id") DO NOTHING;--> statement-breakpoint
|
||||
|
||||
UPDATE "training_records"
|
||||
SET "submitted_by_user_id" = COALESCE("submitted_by_user_id", "created_by")
|
||||
WHERE "submitted_by_user_id" IS NULL;--> statement-breakpoint
|
||||
|
||||
UPDATE "training_records"
|
||||
SET "reviewed_by_user_id" = COALESCE("reviewed_by_user_id", "reviewed_by")
|
||||
WHERE "reviewed_by_user_id" IS NULL AND "reviewed_by" IS NOT NULL;
|
||||
1
drizzle/0011_equal_cannonball.sql
Normal file
1
drizzle/0011_equal_cannonball.sql
Normal file
@@ -0,0 +1 @@
|
||||
CREATE UNIQUE INDEX "employee_training_targets_org_employee_year_idx" ON "employee_training_targets" USING btree ("organization_id","employee_id","year");
|
||||
47
drizzle/0012_change_duration_minutes.sql
Normal file
47
drizzle/0012_change_duration_minutes.sql
Normal file
@@ -0,0 +1,47 @@
|
||||
ALTER TABLE "training_records"
|
||||
ADD COLUMN "submitted_minutes" integer,
|
||||
ADD COLUMN "approved_minutes" integer;
|
||||
|
||||
UPDATE "training_records"
|
||||
SET
|
||||
"submitted_minutes" = ROUND("hours" * 60),
|
||||
"approved_minutes" = CASE
|
||||
WHEN "approved_hours" IS NULL THEN NULL
|
||||
ELSE ROUND("approved_hours" * 60)
|
||||
END
|
||||
WHERE "submitted_minutes" IS NULL
|
||||
OR ("approved_hours" IS NOT NULL AND "approved_minutes" IS NULL);
|
||||
|
||||
ALTER TABLE "training_policies"
|
||||
ADD COLUMN "total_target_minutes" integer,
|
||||
ADD COLUMN "k_target_minutes" integer,
|
||||
ADD COLUMN "s_target_minutes" integer,
|
||||
ADD COLUMN "a_target_minutes" integer;
|
||||
|
||||
UPDATE "training_policies"
|
||||
SET
|
||||
"total_target_minutes" = ROUND("total_hours" * 60),
|
||||
"k_target_minutes" = ROUND("k_hours" * 60),
|
||||
"s_target_minutes" = ROUND("s_hours" * 60),
|
||||
"a_target_minutes" = ROUND("a_hours" * 60)
|
||||
WHERE "total_target_minutes" IS NULL
|
||||
OR "k_target_minutes" IS NULL
|
||||
OR "s_target_minutes" IS NULL
|
||||
OR "a_target_minutes" IS NULL;
|
||||
|
||||
ALTER TABLE "employee_training_targets"
|
||||
ADD COLUMN "total_target_minutes" integer,
|
||||
ADD COLUMN "k_target_minutes" integer,
|
||||
ADD COLUMN "s_target_minutes" integer,
|
||||
ADD COLUMN "a_target_minutes" integer;
|
||||
|
||||
UPDATE "employee_training_targets"
|
||||
SET
|
||||
"total_target_minutes" = ROUND("total_hours" * 60),
|
||||
"k_target_minutes" = ROUND("k_hours" * 60),
|
||||
"s_target_minutes" = ROUND("s_hours" * 60),
|
||||
"a_target_minutes" = ROUND("a_hours" * 60)
|
||||
WHERE "total_target_minutes" IS NULL
|
||||
OR "k_target_minutes" IS NULL
|
||||
OR "s_target_minutes" IS NULL
|
||||
OR "a_target_minutes" IS NULL;
|
||||
80
drizzle/0013_glamorous_mysterio.sql
Normal file
80
drizzle/0013_glamorous_mysterio.sql
Normal file
@@ -0,0 +1,80 @@
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_type
|
||||
WHERE typname = 'online_lesson_status'
|
||||
) THEN
|
||||
CREATE TYPE "public"."online_lesson_status" AS ENUM('draft', 'published', 'archived');
|
||||
END IF;
|
||||
END $$;--> statement-breakpoint
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "online_lessons" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
"organization_id" text NOT NULL,
|
||||
"title" text NOT NULL,
|
||||
"description" text,
|
||||
"category" text,
|
||||
"video_url" text,
|
||||
"video_file_name" text,
|
||||
"video_file_type" text,
|
||||
"video_file_size" integer,
|
||||
"video_storage_key" text,
|
||||
"video_file_url" text,
|
||||
"attachment_file_name" text,
|
||||
"attachment_file_type" text,
|
||||
"attachment_file_size" integer,
|
||||
"attachment_storage_key" text,
|
||||
"attachment_file_url" text,
|
||||
"thumbnail_file_name" text,
|
||||
"thumbnail_file_type" text,
|
||||
"thumbnail_file_size" integer,
|
||||
"thumbnail_storage_key" text,
|
||||
"thumbnail_url" text,
|
||||
"status" "online_lesson_status" DEFAULT 'draft' NOT NULL,
|
||||
"is_published" boolean DEFAULT false NOT NULL,
|
||||
"published_at" timestamp with time zone,
|
||||
"created_by" text NOT NULL,
|
||||
"updated_by" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);--> statement-breakpoint
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'online_lessons_organization_id_organizations_id_fk'
|
||||
) THEN
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD CONSTRAINT "online_lessons_organization_id_organizations_id_fk"
|
||||
FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;
|
||||
END IF;
|
||||
END $$;--> statement-breakpoint
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'online_lessons_created_by_users_id_fk'
|
||||
) THEN
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD CONSTRAINT "online_lessons_created_by_users_id_fk"
|
||||
FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;
|
||||
END IF;
|
||||
END $$;--> statement-breakpoint
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'online_lessons_updated_by_users_id_fk'
|
||||
) THEN
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD CONSTRAINT "online_lessons_updated_by_users_id_fk"
|
||||
FOREIGN KEY ("updated_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
END IF;
|
||||
END $$;
|
||||
1
drizzle/0014_sweet_nico_minoru.sql
Normal file
1
drizzle/0014_sweet_nico_minoru.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TYPE "public"."approval_status" ADD VALUE 'draft' BEFORE 'pending';
|
||||
131
drizzle/0015_permission_template_authorization.sql
Normal file
131
drizzle/0015_permission_template_authorization.sql
Normal file
@@ -0,0 +1,131 @@
|
||||
CREATE TYPE "public"."permission_override_effect" AS ENUM('allow', 'deny');
|
||||
|
||||
CREATE TABLE "permission_templates" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "permission_templates_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"code" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"description" text,
|
||||
"is_system" boolean DEFAULT false NOT NULL,
|
||||
"is_default" boolean DEFAULT false NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"deleted_at" timestamp with time zone,
|
||||
"created_by" text,
|
||||
"updated_by" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "permission_template_permissions" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "permission_template_permissions_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"template_id" integer NOT NULL,
|
||||
"permission" text NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "user_permission_template_assignments" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "user_permission_template_assignments_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"template_id" integer NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"assigned_by" text,
|
||||
"assigned_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "user_permission_overrides" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "user_permission_overrides_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"permission" text NOT NULL,
|
||||
"effect" "permission_override_effect" NOT NULL,
|
||||
"reason" text,
|
||||
"expires_at" timestamp with time zone,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"created_by" text,
|
||||
"revoked_by" text,
|
||||
"revoked_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "permission_audit_logs" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "permission_audit_logs_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text,
|
||||
"actor_user_id" text,
|
||||
"target_user_id" text,
|
||||
"template_id" integer,
|
||||
"assignment_id" integer,
|
||||
"override_id" integer,
|
||||
"action" text NOT NULL,
|
||||
"reason" text,
|
||||
"before" jsonb,
|
||||
"after" jsonb,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE "permission_templates"
|
||||
ADD CONSTRAINT "permission_templates_organization_id_organizations_id_fk"
|
||||
FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;
|
||||
ALTER TABLE "permission_templates"
|
||||
ADD CONSTRAINT "permission_templates_created_by_users_id_fk"
|
||||
FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
ALTER TABLE "permission_templates"
|
||||
ADD CONSTRAINT "permission_templates_updated_by_users_id_fk"
|
||||
FOREIGN KEY ("updated_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
|
||||
ALTER TABLE "permission_template_permissions"
|
||||
ADD CONSTRAINT "permission_template_permissions_template_id_permission_templates_id_fk"
|
||||
FOREIGN KEY ("template_id") REFERENCES "public"."permission_templates"("id") ON DELETE cascade ON UPDATE no action;
|
||||
|
||||
ALTER TABLE "user_permission_template_assignments"
|
||||
ADD CONSTRAINT "user_permission_template_assignments_organization_id_organizations_id_fk"
|
||||
FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;
|
||||
ALTER TABLE "user_permission_template_assignments"
|
||||
ADD CONSTRAINT "user_permission_template_assignments_user_id_users_id_fk"
|
||||
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
|
||||
ALTER TABLE "user_permission_template_assignments"
|
||||
ADD CONSTRAINT "user_permission_template_assignments_template_id_permission_templates_id_fk"
|
||||
FOREIGN KEY ("template_id") REFERENCES "public"."permission_templates"("id") ON DELETE restrict ON UPDATE no action;
|
||||
ALTER TABLE "user_permission_template_assignments"
|
||||
ADD CONSTRAINT "user_permission_template_assignments_assigned_by_users_id_fk"
|
||||
FOREIGN KEY ("assigned_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
|
||||
ALTER TABLE "user_permission_overrides"
|
||||
ADD CONSTRAINT "user_permission_overrides_organization_id_organizations_id_fk"
|
||||
FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;
|
||||
ALTER TABLE "user_permission_overrides"
|
||||
ADD CONSTRAINT "user_permission_overrides_user_id_users_id_fk"
|
||||
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
|
||||
ALTER TABLE "user_permission_overrides"
|
||||
ADD CONSTRAINT "user_permission_overrides_created_by_users_id_fk"
|
||||
FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
ALTER TABLE "user_permission_overrides"
|
||||
ADD CONSTRAINT "user_permission_overrides_revoked_by_users_id_fk"
|
||||
FOREIGN KEY ("revoked_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
|
||||
ALTER TABLE "permission_audit_logs"
|
||||
ADD CONSTRAINT "permission_audit_logs_organization_id_organizations_id_fk"
|
||||
FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE set null ON UPDATE no action;
|
||||
ALTER TABLE "permission_audit_logs"
|
||||
ADD CONSTRAINT "permission_audit_logs_actor_user_id_users_id_fk"
|
||||
FOREIGN KEY ("actor_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
ALTER TABLE "permission_audit_logs"
|
||||
ADD CONSTRAINT "permission_audit_logs_target_user_id_users_id_fk"
|
||||
FOREIGN KEY ("target_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
ALTER TABLE "permission_audit_logs"
|
||||
ADD CONSTRAINT "permission_audit_logs_template_id_permission_templates_id_fk"
|
||||
FOREIGN KEY ("template_id") REFERENCES "public"."permission_templates"("id") ON DELETE set null ON UPDATE no action;
|
||||
ALTER TABLE "permission_audit_logs"
|
||||
ADD CONSTRAINT "permission_audit_logs_assignment_id_user_permission_template_assignments_id_fk"
|
||||
FOREIGN KEY ("assignment_id") REFERENCES "public"."user_permission_template_assignments"("id") ON DELETE set null ON UPDATE no action;
|
||||
ALTER TABLE "permission_audit_logs"
|
||||
ADD CONSTRAINT "permission_audit_logs_override_id_user_permission_overrides_id_fk"
|
||||
FOREIGN KEY ("override_id") REFERENCES "public"."user_permission_overrides"("id") ON DELETE set null ON UPDATE no action;
|
||||
|
||||
CREATE UNIQUE INDEX "permission_templates_org_code_idx" ON "permission_templates" USING btree ("organization_id", "code");
|
||||
CREATE UNIQUE INDEX "permission_templates_org_name_idx" ON "permission_templates" USING btree ("organization_id", "name");
|
||||
CREATE UNIQUE INDEX "permission_template_permissions_template_permission_idx" ON "permission_template_permissions" USING btree ("template_id", "permission");
|
||||
CREATE UNIQUE INDEX "user_permission_template_assignments_org_user_template_idx" ON "user_permission_template_assignments" USING btree ("organization_id", "user_id", "template_id");
|
||||
89
drizzle/0016_curious_giant_man.sql
Normal file
89
drizzle/0016_curious_giant_man.sql
Normal file
@@ -0,0 +1,89 @@
|
||||
CREATE TYPE "public"."permission_override_effect" AS ENUM('allow', 'deny');--> statement-breakpoint
|
||||
CREATE TABLE "permission_audit_logs" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "permission_audit_logs_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text,
|
||||
"actor_user_id" text,
|
||||
"target_user_id" text,
|
||||
"template_id" integer,
|
||||
"assignment_id" integer,
|
||||
"override_id" integer,
|
||||
"action" text NOT NULL,
|
||||
"reason" text,
|
||||
"before" jsonb,
|
||||
"after" jsonb,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "permission_template_permissions" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "permission_template_permissions_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"template_id" integer NOT NULL,
|
||||
"permission" text NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "permission_templates" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "permission_templates_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"code" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"description" text,
|
||||
"is_system" boolean DEFAULT false NOT NULL,
|
||||
"is_default" boolean DEFAULT false NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"deleted_at" timestamp with time zone,
|
||||
"created_by" text,
|
||||
"updated_by" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "user_permission_overrides" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "user_permission_overrides_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"permission" text NOT NULL,
|
||||
"effect" "permission_override_effect" NOT NULL,
|
||||
"reason" text,
|
||||
"expires_at" timestamp with time zone,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"created_by" text,
|
||||
"revoked_by" text,
|
||||
"revoked_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "user_permission_template_assignments" (
|
||||
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "user_permission_template_assignments_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||
"organization_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"template_id" integer NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"assigned_by" text,
|
||||
"assigned_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "permission_audit_logs" ADD CONSTRAINT "permission_audit_logs_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_audit_logs" ADD CONSTRAINT "permission_audit_logs_actor_user_id_users_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_audit_logs" ADD CONSTRAINT "permission_audit_logs_target_user_id_users_id_fk" FOREIGN KEY ("target_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_audit_logs" ADD CONSTRAINT "permission_audit_logs_template_id_permission_templates_id_fk" FOREIGN KEY ("template_id") REFERENCES "public"."permission_templates"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_audit_logs" ADD CONSTRAINT "permission_audit_logs_assignment_id_user_permission_template_assignments_id_fk" FOREIGN KEY ("assignment_id") REFERENCES "public"."user_permission_template_assignments"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_audit_logs" ADD CONSTRAINT "permission_audit_logs_override_id_user_permission_overrides_id_fk" FOREIGN KEY ("override_id") REFERENCES "public"."user_permission_overrides"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_template_permissions" ADD CONSTRAINT "permission_template_permissions_template_id_permission_templates_id_fk" FOREIGN KEY ("template_id") REFERENCES "public"."permission_templates"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_templates" ADD CONSTRAINT "permission_templates_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_templates" ADD CONSTRAINT "permission_templates_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "permission_templates" ADD CONSTRAINT "permission_templates_updated_by_users_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_overrides" ADD CONSTRAINT "user_permission_overrides_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_overrides" ADD CONSTRAINT "user_permission_overrides_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_overrides" ADD CONSTRAINT "user_permission_overrides_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_overrides" ADD CONSTRAINT "user_permission_overrides_revoked_by_users_id_fk" FOREIGN KEY ("revoked_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_template_assignments" ADD CONSTRAINT "user_permission_template_assignments_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_template_assignments" ADD CONSTRAINT "user_permission_template_assignments_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_template_assignments" ADD CONSTRAINT "user_permission_template_assignments_template_id_permission_templates_id_fk" FOREIGN KEY ("template_id") REFERENCES "public"."permission_templates"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permission_template_assignments" ADD CONSTRAINT "user_permission_template_assignments_assigned_by_users_id_fk" FOREIGN KEY ("assigned_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "permission_template_permissions_template_permission_idx" ON "permission_template_permissions" USING btree ("template_id","permission");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "permission_templates_org_code_idx" ON "permission_templates" USING btree ("organization_id","code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "permission_templates_org_name_idx" ON "permission_templates" USING btree ("organization_id","name");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "user_permission_template_assignments_org_user_template_idx" ON "user_permission_template_assignments" USING btree ("organization_id","user_id","template_id");
|
||||
4
drizzle/0017_flowery_moondragon.sql
Normal file
4
drizzle/0017_flowery_moondragon.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE "organizations" ADD COLUMN "is_active" boolean DEFAULT true NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "organizations" ADD COLUMN "deleted_at" timestamp with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "organizations" ADD COLUMN "deleted_by" text;--> statement-breakpoint
|
||||
ALTER TABLE "organizations" ADD CONSTRAINT "organizations_deleted_by_users_id_fk" FOREIGN KEY ("deleted_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
24
drizzle/0018_organizations_soft_delete_repair.sql
Normal file
24
drizzle/0018_organizations_soft_delete_repair.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
ALTER TABLE "organizations"
|
||||
ADD COLUMN IF NOT EXISTS "is_active" boolean DEFAULT true NOT NULL;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "organizations"
|
||||
ADD COLUMN IF NOT EXISTS "deleted_at" timestamp with time zone;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "organizations"
|
||||
ADD COLUMN IF NOT EXISTS "deleted_by" text;
|
||||
--> statement-breakpoint
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'organizations_deleted_by_users_id_fk'
|
||||
) THEN
|
||||
ALTER TABLE "organizations"
|
||||
ADD CONSTRAINT "organizations_deleted_by_users_id_fk"
|
||||
FOREIGN KEY ("deleted_by")
|
||||
REFERENCES "public"."users"("id")
|
||||
ON DELETE set null
|
||||
ON UPDATE no action;
|
||||
END IF;
|
||||
END $$;
|
||||
102
drizzle/0019_content_approval_workflow.sql
Normal file
102
drizzle/0019_content_approval_workflow.sql
Normal file
@@ -0,0 +1,102 @@
|
||||
ALTER TYPE "public"."announcement_status" ADD VALUE IF NOT EXISTS 'pending_review';
|
||||
ALTER TYPE "public"."announcement_status" ADD VALUE IF NOT EXISTS 'approved';
|
||||
ALTER TYPE "public"."announcement_status" ADD VALUE IF NOT EXISTS 'returned';
|
||||
ALTER TYPE "public"."announcement_status" ADD VALUE IF NOT EXISTS 'rejected';
|
||||
|
||||
ALTER TYPE "public"."online_lesson_status" ADD VALUE IF NOT EXISTS 'pending_review';
|
||||
ALTER TYPE "public"."online_lesson_status" ADD VALUE IF NOT EXISTS 'approved';
|
||||
ALTER TYPE "public"."online_lesson_status" ADD VALUE IF NOT EXISTS 'returned';
|
||||
ALTER TYPE "public"."online_lesson_status" ADD VALUE IF NOT EXISTS 'rejected';
|
||||
|
||||
ALTER TABLE "announcements"
|
||||
ADD COLUMN IF NOT EXISTS "submitted_at" timestamp with time zone,
|
||||
ADD COLUMN IF NOT EXISTS "submitted_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "reviewed_at" timestamp with time zone,
|
||||
ADD COLUMN IF NOT EXISTS "reviewed_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "approved_at" timestamp with time zone,
|
||||
ADD COLUMN IF NOT EXISTS "approved_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "published_at" timestamp with time zone,
|
||||
ADD COLUMN IF NOT EXISTS "published_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "review_comment" text;
|
||||
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD COLUMN IF NOT EXISTS "submitted_at" timestamp with time zone,
|
||||
ADD COLUMN IF NOT EXISTS "submitted_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "reviewed_at" timestamp with time zone,
|
||||
ADD COLUMN IF NOT EXISTS "reviewed_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "approved_at" timestamp with time zone,
|
||||
ADD COLUMN IF NOT EXISTS "approved_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "published_by" text,
|
||||
ADD COLUMN IF NOT EXISTS "review_comment" text;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "announcements"
|
||||
ADD CONSTRAINT "announcements_submitted_by_users_id_fk"
|
||||
FOREIGN KEY ("submitted_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "announcements"
|
||||
ADD CONSTRAINT "announcements_reviewed_by_users_id_fk"
|
||||
FOREIGN KEY ("reviewed_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "announcements"
|
||||
ADD CONSTRAINT "announcements_approved_by_users_id_fk"
|
||||
FOREIGN KEY ("approved_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "announcements"
|
||||
ADD CONSTRAINT "announcements_published_by_users_id_fk"
|
||||
FOREIGN KEY ("published_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD CONSTRAINT "online_lessons_submitted_by_users_id_fk"
|
||||
FOREIGN KEY ("submitted_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD CONSTRAINT "online_lessons_reviewed_by_users_id_fk"
|
||||
FOREIGN KEY ("reviewed_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD CONSTRAINT "online_lessons_approved_by_users_id_fk"
|
||||
FOREIGN KEY ("approved_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
ALTER TABLE "online_lessons"
|
||||
ADD CONSTRAINT "online_lessons_published_by_users_id_fk"
|
||||
FOREIGN KEY ("published_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN NULL;
|
||||
END $$;
|
||||
317
drizzle/meta/0000_snapshot.json
Normal file
317
drizzle/meta/0000_snapshot.json
Normal file
@@ -0,0 +1,317 @@
|
||||
{
|
||||
"id": "ae7121c5-e461-44b8-8b25-7f5459f3ad7c",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.memberships": {
|
||||
"name": "memberships",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"organization_id": {
|
||||
"name": "organization_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"role": {
|
||||
"name": "role",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'owner'"
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"type": "text[]",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'{}'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.organizations": {
|
||||
"name": "organizations",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"image_url": {
|
||||
"name": "image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"plan": {
|
||||
"name": "plan",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"created_by": {
|
||||
"name": "created_by",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"organizations_slug_idx": {
|
||||
"name": "organizations_slug_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "slug",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": true,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.products": {
|
||||
"name": "products",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"identity": {
|
||||
"type": "always",
|
||||
"name": "products_id_seq",
|
||||
"schema": "public",
|
||||
"increment": "1",
|
||||
"startWith": "1",
|
||||
"minValue": "1",
|
||||
"maxValue": "2147483647",
|
||||
"cache": "1",
|
||||
"cycle": false
|
||||
}
|
||||
},
|
||||
"organization_id": {
|
||||
"name": "organization_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"category": {
|
||||
"name": "category",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"photo_url": {
|
||||
"name": "photo_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"price": {
|
||||
"name": "price",
|
||||
"type": "double precision",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"active_organization_id": {
|
||||
"name": "active_organization_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"users_email_idx": {
|
||||
"name": "users_email_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "email",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": true,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"roles": {},
|
||||
"policies": {},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
1457
drizzle/meta/0001_snapshot.json
Normal file
1457
drizzle/meta/0001_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1486
drizzle/meta/0002_snapshot.json
Normal file
1486
drizzle/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1541
drizzle/meta/0005_snapshot.json
Normal file
1541
drizzle/meta/0005_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2309
drizzle/meta/0007_snapshot.json
Normal file
2309
drizzle/meta/0007_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2330
drizzle/meta/0008_snapshot.json
Normal file
2330
drizzle/meta/0008_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2643
drizzle/meta/0009_snapshot.json
Normal file
2643
drizzle/meta/0009_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2844
drizzle/meta/0010_snapshot.json
Normal file
2844
drizzle/meta/0010_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2871
drizzle/meta/0011_snapshot.json
Normal file
2871
drizzle/meta/0011_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
3177
drizzle/meta/0013_snapshot.json
Normal file
3177
drizzle/meta/0013_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
3178
drizzle/meta/0014_snapshot.json
Normal file
3178
drizzle/meta/0014_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
3959
drizzle/meta/0016_snapshot.json
Normal file
3959
drizzle/meta/0016_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
3991
drizzle/meta/0017_snapshot.json
Normal file
3991
drizzle/meta/0017_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
146
drizzle/meta/_journal.json
Normal file
146
drizzle/meta/_journal.json
Normal file
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1780621204596,
|
||||
"tag": "0000_married_ink",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1780624516901,
|
||||
"tag": "0001_fancy_wolfpack",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1780642551848,
|
||||
"tag": "0002_unusual_whirlwind",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1780664200000,
|
||||
"tag": "0003_unify_users_training",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1788638400000,
|
||||
"tag": "0004_free_text_training_courses",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1780669454315,
|
||||
"tag": "0005_training_record_employee_id_nullable",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1788639600000,
|
||||
"tag": "0006_training_record_employee_id_nullable_fix",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1781162457987,
|
||||
"tag": "0007_sticky_korath",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1782110903496,
|
||||
"tag": "0008_nosy_robin_chapel",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1782359921598,
|
||||
"tag": "0009_lean_hobgoblin",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1782364383108,
|
||||
"tag": "0010_romantic_marauders",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1782368062128,
|
||||
"tag": "0011_equal_cannonball",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1782896400000,
|
||||
"tag": "0012_change_duration_minutes",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1782713460067,
|
||||
"tag": "0013_glamorous_mysterio",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1783322920425,
|
||||
"tag": "0014_sweet_nico_minoru",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 15,
|
||||
"version": "7",
|
||||
"when": 1783386000000,
|
||||
"tag": "0015_permission_template_authorization",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 16,
|
||||
"version": "7",
|
||||
"when": 1783401232038,
|
||||
"tag": "0016_curious_giant_man",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "7",
|
||||
"when": 1783496392790,
|
||||
"tag": "0017_flowery_moondragon",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 18,
|
||||
"version": "7",
|
||||
"when": 1783899000000,
|
||||
"tag": "0018_organizations_soft_delete_repair",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 19,
|
||||
"version": "7",
|
||||
"when": 1789251000000,
|
||||
"tag": "0019_content_approval_workflow",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user