Add role-based visibility and management features for products

- Introduced a role-based visibility system for products, ensuring that only users with approved roles can view specific products.
- Added new database tables for roles, user roles, and product role visibility to manage access control.
- Implemented utility functions for role management, including fetching approved roles, checking product visibility, and assigning roles to users and products.
- Updated API endpoints to filter products based on user roles, enhancing security and user experience.
- Prepared the database schema for future role request and approval workflows in upcoming phases.
This commit is contained in:
Bastian Masanek
2025-11-02 10:17:40 +01:00
parent 6e4f858883
commit ff9960edef
10 changed files with 1865 additions and 26 deletions

View File

@@ -0,0 +1,43 @@
CREATE TYPE "public"."role_code" AS ENUM('private', 'educator', 'company');--> statement-breakpoint
CREATE TYPE "public"."role_request_status" AS ENUM('pending', 'approved', 'rejected');--> statement-breakpoint
CREATE TABLE "product_role_visibility" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"product_id" uuid NOT NULL,
"role_id" uuid NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "roles" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"code" "role_code" NOT NULL,
"display_name" text NOT NULL,
"description" text NOT NULL,
"requires_approval" boolean DEFAULT false NOT NULL,
"sort_order" integer DEFAULT 0 NOT NULL,
"active" boolean DEFAULT true NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
CONSTRAINT "roles_code_unique" UNIQUE("code")
);
--> statement-breakpoint
CREATE TABLE "user_roles" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"role_id" uuid NOT NULL,
"status" "role_request_status" DEFAULT 'pending' NOT NULL,
"organization_name" text,
"admin_notes" text,
"status_history" jsonb DEFAULT '[]' NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "product_role_visibility" ADD CONSTRAINT "product_role_visibility_product_id_products_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "product_role_visibility" ADD CONSTRAINT "product_role_visibility_role_id_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_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_roles" ADD CONSTRAINT "user_roles_role_id_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "product_role_visibility_product_id_role_id_unique" ON "product_role_visibility" USING btree ("product_id","role_id");--> statement-breakpoint
CREATE INDEX "product_role_visibility_product_id_idx" ON "product_role_visibility" USING btree ("product_id");--> statement-breakpoint
CREATE INDEX "user_roles_user_id_role_id_unique" ON "user_roles" USING btree ("user_id","role_id");--> statement-breakpoint
CREATE INDEX "user_roles_user_id_idx" ON "user_roles" USING btree ("user_id");--> statement-breakpoint
CREATE INDEX "user_roles_status_idx" ON "user_roles" USING btree ("status");