forked from wangziqi/gongxue-base
87 lines
3.9 KiB
SQL
87 lines
3.9 KiB
SQL
create table if not exists public.tenant_classes (
|
|
id uuid primary key default gen_random_uuid(),
|
|
tenant_id uuid not null references public.tenants(id) on delete cascade,
|
|
region_id uuid references public.regions(id) on delete set null,
|
|
legacy_id text,
|
|
code text,
|
|
name text not null,
|
|
description text,
|
|
status text not null default 'active' check (status in ('active', 'disabled', 'archived')),
|
|
sort_order integer not null default 0,
|
|
metadata jsonb not null default '{}'::jsonb,
|
|
created_by uuid references public.platform_users(id) on delete set null,
|
|
updated_by uuid references public.platform_users(id) on delete set null,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
unique (tenant_id, id),
|
|
unique (tenant_id, legacy_id)
|
|
);
|
|
|
|
comment on table public.tenant_classes is
|
|
'Tenant-scoped class/cohort records used for teacher, head-teacher, assistant and student data scopes.';
|
|
|
|
create unique index if not exists idx_tenant_classes_code_unique
|
|
on public.tenant_classes(tenant_id, lower(code))
|
|
where code is not null and code <> '';
|
|
|
|
create index if not exists idx_tenant_classes_tenant_status
|
|
on public.tenant_classes(tenant_id, status, sort_order, created_at desc);
|
|
|
|
create index if not exists idx_tenant_classes_region
|
|
on public.tenant_classes(tenant_id, region_id)
|
|
where region_id is not null;
|
|
|
|
create table if not exists public.tenant_class_members (
|
|
id uuid primary key default gen_random_uuid(),
|
|
tenant_id uuid not null references public.tenants(id) on delete cascade,
|
|
class_id uuid not null,
|
|
user_id uuid not null references public.platform_users(id) on delete cascade,
|
|
member_type text not null check (member_type in ('student', 'teacher', 'assistant', 'head_teacher')),
|
|
status text not null default 'active' check (status in ('active', 'disabled', 'removed')),
|
|
joined_at timestamptz not null default now(),
|
|
left_at timestamptz,
|
|
metadata jsonb not null default '{}'::jsonb,
|
|
created_by uuid references public.platform_users(id) on delete set null,
|
|
updated_by uuid references public.platform_users(id) on delete set null,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
unique (tenant_id, class_id, user_id, member_type),
|
|
foreign key (tenant_id, class_id) references public.tenant_classes(tenant_id, id) on delete cascade
|
|
);
|
|
|
|
comment on table public.tenant_class_members is
|
|
'Class membership assignments. Students can belong to multiple classes; teachers gain scoped visibility through active class memberships.';
|
|
|
|
create index if not exists idx_class_members_tenant_class
|
|
on public.tenant_class_members(tenant_id, class_id, status, member_type);
|
|
|
|
create index if not exists idx_class_members_tenant_user
|
|
on public.tenant_class_members(tenant_id, user_id, status, member_type);
|
|
|
|
alter table public.tenant_classes enable row level security;
|
|
alter table public.tenant_class_members enable row level security;
|
|
|
|
drop policy if exists tenant_isolation on public.tenant_classes;
|
|
create policy tenant_isolation on public.tenant_classes
|
|
for all
|
|
using (tenant_id = app.current_tenant_id() or app.is_platform_admin())
|
|
with check (tenant_id = app.current_tenant_id() or app.is_platform_admin());
|
|
|
|
drop policy if exists tenant_isolation on public.tenant_class_members;
|
|
create policy tenant_isolation on public.tenant_class_members
|
|
for all
|
|
using (tenant_id = app.current_tenant_id() or app.is_platform_admin())
|
|
with check (tenant_id = app.current_tenant_id() or app.is_platform_admin());
|
|
|
|
drop trigger if exists set_updated_at on public.tenant_classes;
|
|
create trigger set_updated_at
|
|
before update on public.tenant_classes
|
|
for each row
|
|
execute function app.touch_updated_at();
|
|
|
|
drop trigger if exists set_updated_at on public.tenant_class_members;
|
|
create trigger set_updated_at
|
|
before update on public.tenant_class_members
|
|
for each row
|
|
execute function app.touch_updated_at();
|