-- Create task_status enum type CREATE TYPE task_status AS ENUM ('todo', 'in_progress', 'in_review', 'done'); -- Create tasks table CREATE TABLE IF NOT EXISTS "public"."tasks" ( "id" "text" DEFAULT "public"."generate_random_string"(24) NOT NULL, "tablo_id" "text" NOT NULL, "title" character varying(500) NOT NULL, "description" "text", "status" task_status DEFAULT 'todo' NOT NULL, "assignee_id" "uuid", "position" integer DEFAULT 0 NOT NULL, "created_at" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, "updated_at" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, CONSTRAINT "tasks_pkey" PRIMARY KEY ("id"), CONSTRAINT "tasks_tablo_id_fkey" FOREIGN KEY ("tablo_id") REFERENCES "public"."tablos"("id") ON DELETE CASCADE, CONSTRAINT "tasks_assignee_id_fkey" FOREIGN KEY ("assignee_id") REFERENCES "auth"."users"("id") ON DELETE SET NULL ); ALTER TABLE "public"."tasks" OWNER TO "postgres"; -- Add comments COMMENT ON TABLE "public"."tasks" IS 'Kanban tasks for tablos'; COMMENT ON COLUMN "public"."tasks"."id" IS 'Primary key: random 24-character alphanumeric string'; COMMENT ON COLUMN "public"."tasks"."tablo_id" IS 'Foreign key to tablos table'; COMMENT ON COLUMN "public"."tasks"."title" IS 'Task title'; COMMENT ON COLUMN "public"."tasks"."description" IS 'Optional task description'; COMMENT ON COLUMN "public"."tasks"."status" IS 'Task status: todo, in_progress, in_review, or done'; COMMENT ON COLUMN "public"."tasks"."assignee_id" IS 'Optional user ID of task assignee'; COMMENT ON COLUMN "public"."tasks"."position" IS 'Position within the column for ordering'; COMMENT ON COLUMN "public"."tasks"."created_at" IS 'Timestamp when the task was created'; COMMENT ON COLUMN "public"."tasks"."updated_at" IS 'Timestamp when the task was last updated (auto-updated by trigger)'; -- Create indexes for better query performance CREATE INDEX "tasks_tablo_id_idx" ON "public"."tasks" USING btree ("tablo_id"); CREATE INDEX "tasks_status_idx" ON "public"."tasks" USING btree ("status"); CREATE INDEX "tasks_assignee_id_idx" ON "public"."tasks" USING btree ("assignee_id"); CREATE INDEX "tasks_position_idx" ON "public"."tasks" USING btree ("tablo_id", "status", "position"); -- Create trigger to auto-update updated_at timestamp CREATE TRIGGER "update_tasks_updated_at" BEFORE UPDATE ON "public"."tasks" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); -- Enable Row Level Security ALTER TABLE "public"."tasks" ENABLE ROW LEVEL SECURITY; -- RLS Policies: Users can only access tasks from tablos they have access to CREATE POLICY "Users can view tasks from their tablos" ON "public"."tasks" FOR SELECT USING ( EXISTS ( SELECT 1 FROM "public"."tablo_access" WHERE "tablo_access"."tablo_id" = "tasks"."tablo_id" AND "tablo_access"."user_id" = auth.uid() AND "tablo_access"."is_active" = true ) ); CREATE POLICY "Users can create tasks in their tablos" ON "public"."tasks" FOR INSERT WITH CHECK ( EXISTS ( SELECT 1 FROM "public"."tablo_access" WHERE "tablo_access"."tablo_id" = "tasks"."tablo_id" AND "tablo_access"."user_id" = auth.uid() AND "tablo_access"."is_active" = true ) ); CREATE POLICY "Users can update tasks in their tablos" ON "public"."tasks" FOR UPDATE USING ( EXISTS ( SELECT 1 FROM "public"."tablo_access" WHERE "tablo_access"."tablo_id" = "tasks"."tablo_id" AND "tablo_access"."user_id" = auth.uid() AND "tablo_access"."is_active" = true ) ); CREATE POLICY "Users can delete tasks in their tablos" ON "public"."tasks" FOR DELETE USING ( EXISTS ( SELECT 1 FROM "public"."tablo_access" WHERE "tablo_access"."tablo_id" = "tasks"."tablo_id" AND "tablo_access"."user_id" = auth.uid() AND "tablo_access"."is_active" = true ) ); -- Create a view that includes assignee information CREATE OR REPLACE VIEW "public"."tasks_with_assignee" WITH ("security_invoker"='true') AS SELECT t.id, t.tablo_id, t.title, t.description, t.status, t.assignee_id, t.position, t.created_at, t.updated_at, p.name AS assignee_name, p.avatar_url AS assignee_avatar FROM "public"."tasks" t LEFT JOIN "public"."profiles" p ON t.assignee_id = p.id; ALTER TABLE "public"."tasks_with_assignee" OWNER TO "postgres"; COMMENT ON VIEW "public"."tasks_with_assignee" IS 'View that returns tasks with assignee information from profiles';