db: squash migrations
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
<script lang="ts">
|
||||
let count = 0;
|
||||
|
||||
function handleClick() {
|
||||
count += 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<button on:click={handleClick}>
|
||||
clicks: {count}
|
||||
</button>
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "svelte-ui",
|
||||
"version": "0.0.0",
|
||||
"description": "Styles and components for use in svelte websites",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "prettier --check --ignore-path=../../.prettierignore .",
|
||||
"format": "prettier --write --ignore-path=../../.prettierignore ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"svelte": "^3.9.2"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
alter table "public"."profile" alter column "avatar_url" set default 'https://pgrest.classroomio.com/storage/v1/object/public/avatars/avatar.png'::text;
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
drop function if exists "public"."get_courses"(org_id_arg uuid, profile_id_arg uuid);
|
||||
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_courses(org_id_arg uuid, profile_id_arg uuid)
|
||||
RETURNS TABLE(id uuid, org_id uuid, title character varying, slug character varying, description character varying, logo text, banner_image text, cost bigint, currency character varying, is_published boolean, profile_id uuid, role_id bigint, total_lessons bigint, total_students bigint, progress_rate bigint)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
Return query
|
||||
select course.id, organization.id AS org_id, course.title, course.slug, course.description, course.logo, course.banner_image, course.cost, course.currency, course.is_published, groupmember.profile_id, groupmember.role_id, (select COUNT(*) from lesson as l where l.course_id = course.id) AS total_lessons, (select COUNT(*) from groupmember as gm where gm.group_id = course.group_id AND gm.role_id = 3) as total_students, (select COUNT(*) from lesson_completion as lc join lesson as l on l.id = lc.lesson_id where l.course_id = course.id and lc.is_complete = true and lc.profile_id = profile_id_arg) AS progress_rate
|
||||
from course
|
||||
join "group" on "group".id = course.group_id
|
||||
join groupmember on groupmember.group_id = course.group_id
|
||||
join organization on organization.id = "group".organization_id
|
||||
where course.status = 'ACTIVE' AND organization.id = org_id_arg
|
||||
-- GROUP BY course.id, groupmember.profile_id
|
||||
ORDER BY course.created_at DESC;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
@@ -1 +0,0 @@
|
||||
alter table "public"."course" alter column "metadata" set default '{"goals": "", "description": "", "requirements": ""}'::jsonb;
|
||||
@@ -1,11 +0,0 @@
|
||||
alter table "public"."community_answer" add column "author_profile_id" uuid;
|
||||
|
||||
alter table "public"."community_question" add column "author_profile_id" uuid;
|
||||
|
||||
alter table "public"."community_answer" add constraint "community_answer_author_profile_id_fkey" FOREIGN KEY (author_profile_id) REFERENCES profile(id) not valid;
|
||||
|
||||
alter table "public"."community_answer" validate constraint "community_answer_author_profile_id_fkey";
|
||||
|
||||
alter table "public"."community_question" add constraint "community_question_author_profile_id_fkey" FOREIGN KEY (author_profile_id) REFERENCES profile(id) not valid;
|
||||
|
||||
alter table "public"."community_question" validate constraint "community_question_author_profile_id_fkey";
|
||||
@@ -1,48 +0,0 @@
|
||||
create table "public"."course_newsfeed" (
|
||||
"created_at" timestamp with time zone not null default now(),
|
||||
"author_id" uuid,
|
||||
"content" text,
|
||||
"id" uuid not null default gen_random_uuid(),
|
||||
"course_id" uuid,
|
||||
"reaction" jsonb default '{"clap": [], "smile": [], "thumbsup": [], "thumbsdown": []}'::jsonb,
|
||||
"is_pinned" boolean not null default false
|
||||
);
|
||||
|
||||
|
||||
create table "public"."course_newsfeed_comment" (
|
||||
"created_at" timestamp with time zone not null default now(),
|
||||
"author_id" uuid,
|
||||
"content" text,
|
||||
"id" bigint generated by default as identity not null,
|
||||
"course_newsfeed_id" uuid
|
||||
);
|
||||
|
||||
|
||||
CREATE UNIQUE INDEX course_newsfeed_comment_id_key ON public.course_newsfeed_comment USING btree (id);
|
||||
|
||||
CREATE UNIQUE INDEX course_newsfeed_comment_pkey ON public.course_newsfeed_comment USING btree (id);
|
||||
|
||||
CREATE UNIQUE INDEX course_newsfeed_pkey ON public.course_newsfeed USING btree (id);
|
||||
|
||||
alter table "public"."course_newsfeed" add constraint "course_newsfeed_pkey" PRIMARY KEY using index "course_newsfeed_pkey";
|
||||
|
||||
alter table "public"."course_newsfeed_comment" add constraint "course_newsfeed_comment_pkey" PRIMARY KEY using index
|
||||
"course_newsfeed_comment_pkey";
|
||||
|
||||
alter table "public"."course_newsfeed" add constraint "course_newsfeed_author_id_fkey" FOREIGN KEY (author_id) REFERENCES groupmember(id) not valid;
|
||||
|
||||
alter table "public"."course_newsfeed" validate constraint "course_newsfeed_author_id_fkey";
|
||||
|
||||
alter table "public"."course_newsfeed" add constraint "course_newsfeed_course_id_fkey" FOREIGN KEY (course_id) REFERENCES course(id) not valid;
|
||||
|
||||
alter table "public"."course_newsfeed" validate constraint "course_newsfeed_course_id_fkey";
|
||||
|
||||
alter table "public"."course_newsfeed_comment" add constraint "course_newsfeed_comment_id_key" UNIQUE using index "course_newsfeed_comment_id_key";
|
||||
|
||||
alter table "public"."course_newsfeed_comment" add constraint "course_newsfeed_comment_author_id_fkey" FOREIGN KEY (author_id) REFERENCES groupmember(id) not valid;
|
||||
|
||||
alter table "public"."course_newsfeed_comment" validate constraint "course_newsfeed_comment_author_id_fkey";
|
||||
|
||||
alter table "public"."course_newsfeed_comment" add constraint "course_newsfeed_comment_course_newsfeed_id_fkey" FOREIGN KEY (course_newsfeed_id) REFERENCES course_newsfeed(id) not valid;
|
||||
|
||||
alter table "public"."course_newsfeed_comment" validate constraint "course_newsfeed_comment_course_newsfeed_id_fkey";
|
||||
@@ -1,20 +0,0 @@
|
||||
create sequence "public"."test_tenant_id_seq";
|
||||
|
||||
create table "public"."test_tenant" (
|
||||
"id" integer not null default nextval('test_tenant_id_seq'::regclass),
|
||||
"details" text
|
||||
);
|
||||
|
||||
truncate "public"."community_question" cascade;
|
||||
|
||||
alter table "public"."community_question" add column "course_id" uuid not null;
|
||||
|
||||
alter sequence "public"."test_tenant_id_seq" owned by "public"."test_tenant"."id";
|
||||
|
||||
CREATE UNIQUE INDEX test_tenant_pkey ON public.test_tenant USING btree (id);
|
||||
|
||||
alter table "public"."test_tenant" add constraint "test_tenant_pkey" PRIMARY KEY using index "test_tenant_pkey";
|
||||
|
||||
alter table "public"."community_question" add constraint "community_question_course_id_fkey" FOREIGN KEY (course_id) REFERENCES course(id) not valid;
|
||||
|
||||
alter table "public"."community_question" validate constraint "community_question_course_id_fkey";
|
||||
@@ -1,6 +0,0 @@
|
||||
alter table "public"."profile" add column "is_email_verified" boolean default false;
|
||||
alter table "public"."profile" add column "verified_at" timestamp with time zone;
|
||||
|
||||
CREATE UNIQUE INDEX profile_email_key ON public.profile USING btree (email);
|
||||
|
||||
alter table "public"."profile" add constraint "profile_email_key" UNIQUE using index "profile_email_key";
|
||||
@@ -1,13 +0,0 @@
|
||||
create type "public"."LOCALE" as enum ('en', 'hi', 'fr', 'pt', 'de', 'vi', 'ru', 'es');
|
||||
|
||||
create table
|
||||
public.lesson_language (
|
||||
id bigint generated by default as identity,
|
||||
content text null,
|
||||
lesson_id uuid null default gen_random_uuid (),
|
||||
locale "LOCALE" default 'en'::"LOCALE",
|
||||
constraint lesson_language_pkey primary key (id),
|
||||
constraint public_lesson_language_lesson_id_fkey foreign key (lesson_id) references lesson (id)
|
||||
) tablespace pg_default;
|
||||
|
||||
alter table "public"."profile" add column "locale" "LOCALE" default 'en'::"LOCALE";
|
||||
@@ -1,26 +0,0 @@
|
||||
create type "public"."PLAN" as enum ('EARLY_ADOPTER', 'ENTERPRISE', 'BASIC');
|
||||
|
||||
create table "public"."organization_plan" (
|
||||
"id" bigint generated by default as identity not null,
|
||||
"activated_at" timestamp with time zone not null default now(),
|
||||
"org_id" uuid,
|
||||
"plan_name" "PLAN",
|
||||
"is_active" boolean,
|
||||
"deactivated_at" timestamp with time zone,
|
||||
"updated_at" timestamp with time zone default now(),
|
||||
"payload" jsonb,
|
||||
"triggered_by" bigint
|
||||
);
|
||||
|
||||
|
||||
CREATE UNIQUE INDEX organization_plan_pkey ON public.organization_plan USING btree (id);
|
||||
|
||||
alter table "public"."organization_plan" add constraint "organization_plan_pkey" PRIMARY KEY using index "organization_plan_pkey";
|
||||
|
||||
alter table "public"."organization_plan" add constraint "organization_plan_org_id_fkey" FOREIGN KEY (org_id) REFERENCES organization(id) not valid;
|
||||
|
||||
alter table "public"."organization_plan" validate constraint "organization_plan_org_id_fkey";
|
||||
|
||||
alter table "public"."organization_plan" add constraint "organization_plan_triggered_by_fkey" FOREIGN KEY (triggered_by) REFERENCES organizationmember(id) not valid;
|
||||
|
||||
alter table "public"."organization_plan" validate constraint "organization_plan_triggered_by_fkey";
|
||||
@@ -1 +0,0 @@
|
||||
alter table "public"."submission" add column "feedback" text;
|
||||
@@ -1 +0,0 @@
|
||||
alter table "public"."organization" add column "customization" json not null default '{"apps":{"poll":true,"comments":true},"course":{"grading":true,"newsfeed":true},"dashboard":{"exercise":true,"community":true,"bannerText":"","bannerImage":""}}'::json;
|
||||
@@ -1,37 +0,0 @@
|
||||
create type "public"."COURSE_TYPE" as enum ('SELF_PACED', 'LIVE_CLASS');
|
||||
|
||||
alter table "public"."course" add column "type" "COURSE_TYPE" default 'LIVE_CLASS'::"COURSE_TYPE";
|
||||
|
||||
drop function if exists "public"."get_courses"(org_id_arg uuid, profile_id_arg uuid);
|
||||
|
||||
create
|
||||
or replace function public.get_courses (org_id_arg uuid, profile_id_arg uuid) returns table (
|
||||
id uuid,
|
||||
org_id uuid,
|
||||
title character varying,
|
||||
slug character varying,
|
||||
description character varying,
|
||||
logo text,
|
||||
banner_image text,
|
||||
cost bigint,
|
||||
currency character varying,
|
||||
is_published boolean,
|
||||
profile_id uuid,
|
||||
role_id bigint,
|
||||
total_lessons bigint,
|
||||
total_students bigint,
|
||||
progress_rate bigint,
|
||||
type "COURSE_TYPE"
|
||||
) language plpgsql as $function$
|
||||
BEGIN
|
||||
Return query
|
||||
select course.id, organization.id AS org_id, course.title, course.slug, course.description, course.logo, course.banner_image, course.cost, course.currency, course.is_published, groupmember.profile_id, groupmember.role_id, (select COUNT(*) from lesson as l where l.course_id = course.id) AS total_lessons, (select COUNT(*) from groupmember as gm where gm.group_id = course.group_id AND gm.role_id = 3) as total_students, (select COUNT(*) from lesson_completion as lc join lesson as l on l.id = lc.lesson_id where l.course_id = course.id and lc.is_complete = true and lc.profile_id = profile_id_arg) AS progress_rate, course.type as type
|
||||
from course
|
||||
join "group" on "group".id = course.group_id
|
||||
join groupmember on groupmember.group_id = course.group_id
|
||||
join organization on organization.id = "group".organization_id
|
||||
where course.status = 'ACTIVE' AND organization.id = org_id_arg
|
||||
-- GROUP BY course.id, groupmember.profile_id
|
||||
ORDER BY course.created_at DESC;
|
||||
END;
|
||||
$function$;
|
||||
@@ -1,31 +0,0 @@
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_course_progress(course_id_arg uuid, profile_id_arg uuid)
|
||||
RETURNS TABLE(lessons_count bigint, lessons_completed bigint, exercises_count bigint, exercises_completed bigint)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
select
|
||||
count(lesson.id) as lessons_count,
|
||||
count(lesson_completion.id) as lessons_completed,
|
||||
count(exercise.id) as exercises_count,
|
||||
count(submission.id) as exercises_completed
|
||||
from
|
||||
course
|
||||
join "group" on "group".id = course.group_id
|
||||
join groupmember on groupmember.group_id = course.group_id
|
||||
join profile on profile.id = groupmember.profile_id
|
||||
left join lesson on lesson.course_id = course.id
|
||||
left join lesson_completion on lesson_completion.lesson_id = lesson.id
|
||||
and lesson_completion.is_complete = true
|
||||
and lesson_completion.profile_id = profile.id
|
||||
left join exercise on exercise.lesson_id = lesson.id
|
||||
left join submission on submission.exercise_id = exercise.id
|
||||
and submission.submitted_by = groupmember.id
|
||||
where
|
||||
course.id = course_id_arg
|
||||
and profile.id = profile_id_arg;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
@@ -1,31 +0,0 @@
|
||||
drop function if exists "public"."get_courses"(org_id_arg uuid, profile_id_arg uuid);
|
||||
|
||||
create
|
||||
or replace function public.get_courses (org_id_arg uuid, profile_id_arg uuid) returns table (
|
||||
id uuid,
|
||||
org_id uuid,
|
||||
title character varying,
|
||||
slug character varying,
|
||||
description character varying,
|
||||
logo text,
|
||||
banner_image text,
|
||||
cost bigint,
|
||||
currency character varying,
|
||||
is_published boolean,
|
||||
total_lessons bigint,
|
||||
total_students bigint,
|
||||
progress_rate bigint,
|
||||
type "COURSE_TYPE",
|
||||
member_profile_id uuid
|
||||
) language plpgsql as $function$
|
||||
BEGIN
|
||||
Return query
|
||||
select course.id, organization.id AS org_id, course.title, course.slug, course.description, course.logo, course.banner_image, course.cost, course.currency, course.is_published, (select COUNT(*) from lesson as l where l.course_id = course.id) AS total_lessons, (select COUNT(*) from groupmember as gm where gm.group_id = course.group_id AND gm.role_id = 3) as total_students, (select COUNT(*) from lesson_completion as lc join lesson as l on l.id = lc.lesson_id where l.course_id = course.id and lc.is_complete = true and lc.profile_id = profile_id_arg) AS progress_rate, course.type as type, (select groupmember.profile_id from groupmember where groupmember.group_id = "group".id and groupmember.profile_id = profile_id_arg) as member_profile_id
|
||||
from course
|
||||
join "group" on "group".id = course.group_id
|
||||
join organization on organization.id = "group".organization_id
|
||||
where course.status = 'ACTIVE' AND organization.id = org_id_arg
|
||||
-- GROUP BY course.id, groupmember.profile_id
|
||||
ORDER BY course.created_at DESC;
|
||||
END;
|
||||
$function$;
|
||||
@@ -1,47 +0,0 @@
|
||||
-- Drop table cause it was never used
|
||||
drop table if exists public.lesson_progress;
|
||||
|
||||
alter table public.exercise
|
||||
drop constraint exercise_lesson_id_fkey,
|
||||
add constraint exercise_lesson_id_fkey foreign key (lesson_id) references lesson (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.lesson_comment
|
||||
drop constraint lesson_comment_lesson_id_fkey,
|
||||
add constraint lesson_comment_lesson_id_fkey foreign key (lesson_id) references lesson (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.question
|
||||
drop constraint question_exercise_id_fkey,
|
||||
add constraint question_exercise_id_fkey foreign key (exercise_id) references exercise (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.option
|
||||
drop constraint option_question_id_fkey,
|
||||
add constraint option_question_id_fkey foreign key (question_id) references question (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.question_answer
|
||||
drop constraint question_answer_question_id_fkey,
|
||||
add constraint question_answer_question_id_fkey foreign key (question_id) references question (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.submission
|
||||
drop constraint submission_exercise_id_fkey,
|
||||
add constraint submission_exercise_id_fkey foreign key (exercise_id) references exercise (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.submission
|
||||
drop constraint submission_course_id_fkey,
|
||||
add constraint submission_course_id_fkey foreign key (course_id) references course (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.question_answer
|
||||
drop constraint question_answer_submission_id_fkey,
|
||||
add constraint question_answer_submission_id_fkey foreign key (submission_id) references submission (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table public.lesson_completion
|
||||
drop constraint lesson_completion_lesson_id_fkey,
|
||||
add constraint lesson_completion_lesson_id_fkey foreign key (lesson_id) references lesson (id)
|
||||
on delete cascade;
|
||||
@@ -1,25 +0,0 @@
|
||||
CREATE TABLE lesson_language_history (
|
||||
id SERIAL PRIMARY KEY,
|
||||
lesson_language_id INTEGER REFERENCES lesson_language(id),
|
||||
old_content TEXT,
|
||||
new_content TEXT,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE FUNCTION update_lesson_language_history()
|
||||
RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF TG_OP IN ('INSERT', 'UPDATE') THEN
|
||||
INSERT INTO lesson_language_history (lesson_language_id, old_content, new_content)
|
||||
VALUES (NEW.id, COALESCE(OLD.content, ''), NEW.content);
|
||||
END IF;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
||||
CREATE TRIGGER update_lesson_language_history_trigger
|
||||
AFTER INSERT
|
||||
OR
|
||||
UPDATE ON lesson_language for each row
|
||||
EXECUTE PROCEDURE update_lesson_language_history();
|
||||
@@ -1,7 +0,0 @@
|
||||
create or replace view "public"."lesson_versions" as SELECT llh.old_content,
|
||||
llh.new_content,
|
||||
llh."timestamp",
|
||||
ll.locale,
|
||||
ll.lesson_id
|
||||
FROM (lesson_language_history llh
|
||||
JOIN lesson_language ll ON ((ll.id = llh.lesson_language_id)));
|
||||
@@ -1,17 +0,0 @@
|
||||
CREATE OR REPLACE FUNCTION public.get_explore_courses(org_id_arg uuid, profile_id_arg uuid)
|
||||
RETURNS TABLE(id uuid, org_id uuid, title character varying, slug character varying, description character varying, logo text, banner_image text, cost bigint, currency character varying, is_published boolean, total_lessons bigint, total_students bigint, progress_rate bigint, type "COURSE_TYPE", other_profile_id uuid)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
Return query
|
||||
select course.id, organization.id AS org_id, course.title, course.slug, course.description, course.logo, course.banner_image, course.cost, course.currency, course.is_published, (select COUNT(*) from lesson
|
||||
as l where l.course_id = course.id) AS total_lessons, (select COUNT(*) from groupmember as gm where gm.group_id = course.group_id AND gm.role_id = 3) as total_students, (select COUNT(*) from lesson_completion as lc join lesson as l on l.id = lc.lesson_id where l.course_id = course.id and lc.is_complete = true and lc.profile_id = profile_id_arg) AS progress_rate, course.type as type, (select groupmember.profile_id from groupmember where groupmember.group_id = "group".id and groupmember.profile_id != profile_id_arg
|
||||
limit 1) as other_profile_id
|
||||
from course
|
||||
join "group" on "group".id = course.group_id
|
||||
join organization on organization.id = "group".organization_id
|
||||
where course.status = 'ACTIVE' AND course.is_published = true AND organization.id = org_id_arg AND profile_id_arg NOT IN (SELECT groupmember.profile_id FROM groupmember WHERE groupmember.group_id = course.group_id)
|
||||
ORDER BY course.created_at DESC;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
||||
drop policy "User must be an admin to INSERT" on "public"."organization";
|
||||
|
||||
create policy "Enable insert for authenticated users only"
|
||||
on "public"."organization"
|
||||
as permissive
|
||||
for insert
|
||||
to authenticated
|
||||
with check (true);
|
||||
@@ -1,59 +0,0 @@
|
||||
create policy "User must be an org member to DELETE"
|
||||
on "public"."lesson_language_history"
|
||||
as permissive
|
||||
for delete
|
||||
to public
|
||||
using (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = ( SELECT lesson.course_id
|
||||
FROM lesson
|
||||
WHERE (lesson.id = ( SELECT lesson_language.lesson_id
|
||||
FROM lesson_language
|
||||
WHERE (lesson_language.id = lesson_language_history.lesson_language_id)))
|
||||
LIMIT 1))
|
||||
LIMIT 1)));
|
||||
|
||||
|
||||
create policy "User must be an org member to INSERT"
|
||||
on "public"."lesson_language_history"
|
||||
as permissive
|
||||
for insert
|
||||
to public
|
||||
with check (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = ( SELECT lesson.course_id
|
||||
FROM lesson
|
||||
WHERE (lesson.id = ( SELECT lesson_language.lesson_id
|
||||
FROM lesson_language
|
||||
WHERE (lesson_language.id = lesson_language_history.lesson_language_id)))
|
||||
LIMIT 1))
|
||||
LIMIT 1)));
|
||||
|
||||
|
||||
create policy "User must be an org member to UPDATE"
|
||||
on "public"."lesson_language_history"
|
||||
as permissive
|
||||
for update
|
||||
to public
|
||||
using (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = ( SELECT lesson.course_id
|
||||
FROM lesson
|
||||
WHERE (lesson.id = ( SELECT lesson_language.lesson_id
|
||||
FROM lesson_language
|
||||
WHERE (lesson_language.id = lesson_language_history.lesson_language_id)))
|
||||
LIMIT 1))
|
||||
LIMIT 1)))
|
||||
with check (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = ( SELECT lesson.course_id
|
||||
FROM lesson
|
||||
WHERE (lesson.id = ( SELECT lesson_language.lesson_id
|
||||
FROM lesson_language
|
||||
WHERE (lesson_language.id = lesson_language_history.lesson_language_id)))
|
||||
LIMIT 1))
|
||||
LIMIT 1)));
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
create type "public"."COURSE_VERSION" as enum ('V1', 'V2');
|
||||
|
||||
alter table "public"."lesson_language_history" drop constraint "lesson_language_history_lesson_language_id_fkey";
|
||||
|
||||
alter table "public"."lesson_language" drop constraint "public_lesson_language_lesson_id_fkey";
|
||||
|
||||
create table "public"."lesson_section" (
|
||||
"id" uuid not null default gen_random_uuid(),
|
||||
"created_at" timestamp with time zone not null default now(),
|
||||
"updated_at" timestamp with time zone default now(),
|
||||
"title" character varying,
|
||||
"order" bigint default '0'::bigint,
|
||||
"course_id" uuid
|
||||
);
|
||||
|
||||
|
||||
alter table "public"."lesson_section" enable row level security;
|
||||
|
||||
alter table "public"."course" add column "version" "COURSE_VERSION" not null default 'V1'::"COURSE_VERSION";
|
||||
|
||||
alter table "public"."lesson" add column "section_id" uuid;
|
||||
|
||||
CREATE UNIQUE INDEX lesson_section_pkey ON public.lesson_section USING btree (id);
|
||||
|
||||
alter table "public"."lesson_section" add constraint "lesson_section_pkey" PRIMARY KEY using index "lesson_section_pkey";
|
||||
|
||||
alter table "public"."lesson" add constraint "public_lesson_section_id_fkey" FOREIGN KEY (section_id) REFERENCES lesson_section(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;
|
||||
|
||||
alter table "public"."lesson" validate constraint "public_lesson_section_id_fkey";
|
||||
|
||||
alter table "public"."lesson_language_history" add constraint "public_lesson_language_history_lesson_language_id_fkey" FOREIGN KEY (lesson_language_id) REFERENCES lesson_language(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;
|
||||
|
||||
alter table "public"."lesson_language_history" validate constraint "public_lesson_language_history_lesson_language_id_fkey";
|
||||
|
||||
alter table "public"."lesson_section" add constraint "public_lesson_section_course_id_fkey" FOREIGN KEY (course_id) REFERENCES course(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;
|
||||
|
||||
alter table "public"."lesson_section" validate constraint "public_lesson_section_course_id_fkey";
|
||||
|
||||
alter table "public"."lesson_language" add constraint "public_lesson_language_lesson_id_fkey" FOREIGN KEY (lesson_id) REFERENCES lesson(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;
|
||||
|
||||
alter table "public"."lesson_language" validate constraint "public_lesson_language_lesson_id_fkey";
|
||||
|
||||
grant delete on table "public"."lesson_section" to "anon";
|
||||
|
||||
grant insert on table "public"."lesson_section" to "anon";
|
||||
|
||||
grant references on table "public"."lesson_section" to "anon";
|
||||
|
||||
grant select on table "public"."lesson_section" to "anon";
|
||||
|
||||
grant trigger on table "public"."lesson_section" to "anon";
|
||||
|
||||
grant truncate on table "public"."lesson_section" to "anon";
|
||||
|
||||
grant update on table "public"."lesson_section" to "anon";
|
||||
|
||||
grant delete on table "public"."lesson_section" to "authenticated";
|
||||
|
||||
grant insert on table "public"."lesson_section" to "authenticated";
|
||||
|
||||
grant references on table "public"."lesson_section" to "authenticated";
|
||||
|
||||
grant select on table "public"."lesson_section" to "authenticated";
|
||||
|
||||
grant trigger on table "public"."lesson_section" to "authenticated";
|
||||
|
||||
grant truncate on table "public"."lesson_section" to "authenticated";
|
||||
|
||||
grant update on table "public"."lesson_section" to "authenticated";
|
||||
|
||||
grant delete on table "public"."lesson_section" to "service_role";
|
||||
|
||||
grant insert on table "public"."lesson_section" to "service_role";
|
||||
|
||||
grant references on table "public"."lesson_section" to "service_role";
|
||||
|
||||
grant select on table "public"."lesson_section" to "service_role";
|
||||
|
||||
grant trigger on table "public"."lesson_section" to "service_role";
|
||||
|
||||
grant truncate on table "public"."lesson_section" to "service_role";
|
||||
|
||||
grant update on table "public"."lesson_section" to "service_role";
|
||||
|
||||
create policy "Enable read access for all users"
|
||||
on "public"."lesson_section"
|
||||
as permissive
|
||||
for select
|
||||
to public
|
||||
using (true);
|
||||
|
||||
|
||||
create policy "User must be an org member to DELETE"
|
||||
on "public"."lesson_section"
|
||||
as permissive
|
||||
for delete
|
||||
to public
|
||||
using (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = lesson_section.course_id)
|
||||
LIMIT 1)));
|
||||
|
||||
|
||||
create policy "User must be an org member to INSERT"
|
||||
on "public"."lesson_section"
|
||||
as permissive
|
||||
for insert
|
||||
to public
|
||||
with check (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = lesson_section.course_id)
|
||||
LIMIT 1)));
|
||||
|
||||
|
||||
create policy "User must be an org member to UPDATE"
|
||||
on "public"."lesson_section"
|
||||
as permissive
|
||||
for update
|
||||
to public
|
||||
using (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = lesson_section.course_id)
|
||||
LIMIT 1)))
|
||||
with check (is_user_in_group_with_role(( SELECT course.group_id
|
||||
FROM course
|
||||
WHERE (course.id = lesson_section.course_id)
|
||||
LIMIT 1)));
|
||||
|
||||
CREATE
|
||||
OR REPLACE FUNCTION convert_course_to_v2 (course_id uuid) RETURNS void AS $$
|
||||
DECLARE
|
||||
new_section_id bigint;
|
||||
BEGIN
|
||||
UPDATE course
|
||||
SET version = 'V2'
|
||||
WHERE id = course_id;
|
||||
|
||||
INSERT INTO lesson_section (title, course_id) VALUES ('First Section [edit me]', course_id) RETURNING id INTO new_section_id;
|
||||
|
||||
UPDATE lesson
|
||||
SET section_id = new_section_id
|
||||
WHERE course_id = course_id;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
drop function if exists "public"."convert_course_to_v2"(course_id uuid);
|
||||
|
||||
alter table "public"."organization" add column "is_restricted" boolean not null default false;
|
||||
|
||||
alter table "public"."profile" add column "is_restricted" boolean not null default false;
|
||||
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE
|
||||
OR REPLACE FUNCTION convert_course_to_v2 (course_id_arg uuid) RETURNS void AS $$
|
||||
DECLARE
|
||||
new_section_id uuid;
|
||||
BEGIN
|
||||
UPDATE course
|
||||
SET version = 'V2'
|
||||
WHERE id = course_id_arg;
|
||||
|
||||
INSERT INTO lesson_section (title, course_id) VALUES ('First Section [edit me]', course_id_arg) RETURNING id INTO new_section_id;
|
||||
|
||||
UPDATE lesson
|
||||
SET section_id = new_section_id
|
||||
WHERE lesson.course_id = course_id_arg;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
alter table "public"."organization" add column "customCode" text;
|
||||
|
||||
alter table "public"."organization" add column "customDomain" text;
|
||||
|
||||
alter table "public"."organization" add column "favicon" text;
|
||||
|
||||
alter table "public"."organization" add column "isCustomDomainVerified" boolean default false;
|
||||
|
||||
CREATE UNIQUE INDEX "organization_customDomain_key" ON public.organization USING btree ("customDomain");
|
||||
|
||||
alter table "public"."organization" add constraint "organization_customDomain_key" UNIQUE using index "organization_customDomain_key";
|
||||
@@ -1,8 +0,0 @@
|
||||
drop policy "User must be an org member to SELECT" on "public"."organization_plan";
|
||||
|
||||
create policy "Enable read access for all users"
|
||||
on "public"."organization_plan"
|
||||
as permissive
|
||||
for select
|
||||
to public
|
||||
using (true);
|
||||
@@ -1,125 +0,0 @@
|
||||
create table "public"."analytics_login_events" (
|
||||
"id" uuid not null default uuid_generate_v4(),
|
||||
"user_id" uuid not null,
|
||||
"logged_in_at" timestamp with time zone default now()
|
||||
);
|
||||
|
||||
alter table "public"."analytics_login_events" enable row level security;
|
||||
|
||||
CREATE UNIQUE INDEX analytics_login_events_pkey ON public.analytics_login_events USING btree (id);
|
||||
|
||||
CREATE INDEX idx_analytics_login_events_logged_in_at ON public.analytics_login_events USING btree (logged_in_at);
|
||||
|
||||
CREATE INDEX idx_analytics_login_events_user_id ON public.analytics_login_events USING btree (user_id);
|
||||
|
||||
CREATE UNIQUE INDEX analytics_login_events_user_id_unique ON public.analytics_login_events USING btree (user_id);
|
||||
|
||||
alter table "public"."analytics_login_events" add constraint "analytics_login_events_pkey" PRIMARY KEY using index "analytics_login_events_pkey";
|
||||
|
||||
alter table "public"."analytics_login_events" add constraint "analytics_login_events_user_id_fkey" FOREIGN KEY (user_id) REFERENCES auth.users(id) not valid;
|
||||
|
||||
alter table "public"."analytics_login_events" validate constraint "analytics_login_events_user_id_fkey";
|
||||
|
||||
alter table "public"."analytics_login_events" add constraint "analytics_login_events_user_id_unique" UNIQUE using index "analytics_login_events_user_id_unique";
|
||||
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.insert_login_event_on_user_login()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $function$
|
||||
BEGIN
|
||||
IF (NEW.last_sign_in_at IS NOT NULL) THEN
|
||||
INSERT INTO public.analytics_login_events (logged_in_at, user_id)
|
||||
VALUES (NEW.last_sign_in_at, NEW.id)
|
||||
ON CONFLICT (user_id) DO UPDATE
|
||||
SET logged_in_at = NEW.last_sign_in_at;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE TRIGGER insert_login_event_on_user_login_trigger
|
||||
AFTER UPDATE OF last_sign_in_at ON auth.users
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.insert_login_event_on_user_login();
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.insert_login_event_on_user_session_update()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $function$
|
||||
BEGIN
|
||||
IF (NEW.updated_at IS NOT NULL AND NEW.updated_at != OLD.updated_at) THEN
|
||||
INSERT INTO public.analytics_login_events (logged_in_at, user_id)
|
||||
VALUES (NEW.updated_at, NEW.user_id)
|
||||
ON CONFLICT (user_id) DO UPDATE
|
||||
SET logged_in_at = EXCLUDED.logged_in_at
|
||||
WHERE analytics_login_events.logged_in_at < EXCLUDED.logged_in_at;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE TRIGGER insert_login_event_on_user_session_update_trigger
|
||||
AFTER UPDATE OF updated_at ON auth.sessions
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.insert_login_event_on_user_session_update();
|
||||
|
||||
grant delete on table "public"."analytics_login_events" to "anon";
|
||||
|
||||
grant insert on table "public"."analytics_login_events" to "anon";
|
||||
|
||||
grant references on table "public"."analytics_login_events" to "anon";
|
||||
|
||||
grant select on table "public"."analytics_login_events" to "anon";
|
||||
|
||||
grant trigger on table "public"."analytics_login_events" to "anon";
|
||||
|
||||
grant truncate on table "public"."analytics_login_events" to "anon";
|
||||
|
||||
grant update on table "public"."analytics_login_events" to "anon";
|
||||
|
||||
grant delete on table "public"."analytics_login_events" to "authenticated";
|
||||
|
||||
grant insert on table "public"."analytics_login_events" to "authenticated";
|
||||
|
||||
grant references on table "public"."analytics_login_events" to "authenticated";
|
||||
|
||||
grant select on table "public"."analytics_login_events" to "authenticated";
|
||||
|
||||
grant trigger on table "public"."analytics_login_events" to "authenticated";
|
||||
|
||||
grant truncate on table "public"."analytics_login_events" to "authenticated";
|
||||
|
||||
grant update on table "public"."analytics_login_events" to "authenticated";
|
||||
|
||||
grant delete on table "public"."analytics_login_events" to "service_role";
|
||||
|
||||
grant insert on table "public"."analytics_login_events" to "service_role";
|
||||
|
||||
grant references on table "public"."analytics_login_events" to "service_role";
|
||||
|
||||
grant select on table "public"."analytics_login_events" to "service_role";
|
||||
|
||||
grant trigger on table "public"."analytics_login_events" to "service_role";
|
||||
|
||||
grant truncate on table "public"."analytics_login_events" to "service_role";
|
||||
|
||||
grant update on table "public"."analytics_login_events" to "service_role";
|
||||
|
||||
create policy "Users can insert their own login events"
|
||||
on "public"."analytics_login_events"
|
||||
as permissive
|
||||
for insert
|
||||
to authenticated
|
||||
with check ((auth.uid() = user_id));
|
||||
|
||||
CREATE POLICY "Enable delete for users based on user_id"
|
||||
ON "public"."analytics_login_events"
|
||||
AS PERMISSIVE FOR DELETE
|
||||
TO public
|
||||
USING (auth.uid() = user_id);
|
||||
@@ -1,18 +0,0 @@
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.check_if_student_completed_exercises(lesson_id_arg uuid, groupmember_id_arg uuid)
|
||||
RETURNS boolean
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
all_exercises_exist boolean;
|
||||
BEGIN
|
||||
SELECT COUNT(*) = COUNT(s.id) INTO all_exercises_exist
|
||||
FROM exercise e
|
||||
LEFT JOIN submission s ON e.id = s.exercise_id AND s.submitted_by = groupmember_id_arg
|
||||
WHERE e.lesson_id = lesson_id_arg;
|
||||
|
||||
RETURN all_exercises_exist;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
@@ -1,80 +0,0 @@
|
||||
set check_function_bodies = off;
|
||||
|
||||
create or replace view "public"."dash_org_stats" as SELECT gp.organization_id AS org_id,
|
||||
count(DISTINCT course.id) AS no_of_courses,
|
||||
count(DISTINCT gm.profile_id) AS enrolled_students
|
||||
FROM ((course
|
||||
JOIN "group" gp ON ((gp.id = course.group_id)))
|
||||
LEFT JOIN groupmember gm ON (((gm.group_id = gp.id) AND (gm.role_id = 3))))
|
||||
WHERE (course.status = 'ACTIVE'::text)
|
||||
GROUP BY gp.organization_id;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_dash_org_recent_enrollments(org_id_arg uuid)
|
||||
RETURNS TABLE(profile_id uuid, avatar_url text, fullname text, course_id uuid, course_title character varying, enrolled_at timestamp with time zone)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
p.id,
|
||||
p.avatar_url,
|
||||
p.fullname,
|
||||
course.id,
|
||||
course.title,
|
||||
gm.created_at as enrolled_at
|
||||
FROM
|
||||
course
|
||||
JOIN "group" as gp ON gp.id = course.group_id
|
||||
LEFT JOIN groupmember as gm ON gm.group_id = gp.id AND gm.role_id = 3
|
||||
JOIN profile as p ON p.id = gm.profile_id
|
||||
WHERE
|
||||
course.status = 'ACTIVE'
|
||||
AND gp.organization_id = org_id_arg
|
||||
GROUP BY
|
||||
p.id,
|
||||
course.id,
|
||||
course.title,
|
||||
enrolled_at
|
||||
ORDER BY
|
||||
enrolled_at DESC
|
||||
LIMIT 5;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_dash_org_top_courses(org_id_arg uuid)
|
||||
RETURNS TABLE(course_id uuid, course_title character varying, total_students integer, completion_percentage integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
course_stats.course_id,
|
||||
course_stats.course_title,
|
||||
course_stats.total_students::integer,
|
||||
CASE
|
||||
WHEN course_stats.total_students * course_stats.total_lessons = 0 THEN 0
|
||||
ELSE ROUND((course_stats.completed_lessons::numeric / (course_stats.total_students * course_stats.total_lessons)) * 100)::integer
|
||||
END as completion_percentage
|
||||
FROM (
|
||||
SELECT
|
||||
c.id as course_id,
|
||||
c.title as course_title,
|
||||
COUNT(DISTINCT gm.id) as total_students,
|
||||
COUNT(DISTINCT l.id) as total_lessons,
|
||||
COUNT(DISTINCT lc.id) FILTER (WHERE lc.is_complete = true) as completed_lessons
|
||||
FROM course c
|
||||
JOIN "group" g ON g.id = c.group_id
|
||||
LEFT JOIN groupmember gm ON gm.group_id = g.id and gm.role_id = 3
|
||||
LEFT JOIN lesson l ON l.course_id = c.id
|
||||
LEFT JOIN lesson_completion lc ON lc.lesson_id = l.id
|
||||
AND lc.profile_id = gm.profile_id
|
||||
WHERE c.status = 'ACTIVE' AND g.organization_id = org_id_arg
|
||||
GROUP BY c.id, c.title
|
||||
ORDER BY completed_lessons DESC
|
||||
) as course_stats
|
||||
LIMIT 5;
|
||||
END;
|
||||
$function$
|
||||
;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
alter table "public"."organization_plan" add column "provider" text default 'lmz'::text;
|
||||
|
||||
alter table "public"."organization_plan" add column "subscription_id" text;
|
||||
|
||||
CREATE UNIQUE INDEX organization_plan_subscription_id_key ON public.organization_plan USING btree (subscription_id);
|
||||
|
||||
alter table "public"."organization_plan" add constraint "organization_plan_subscription_id_key" UNIQUE using index "organization_plan_subscription_id_key";
|
||||
Reference in New Issue
Block a user