-- Migration date: 2026-06-13 -- Tabular reviews overview read model. -- Returns visible reviews plus document_count in one database call. create or replace function public.get_tabular_reviews_overview( p_user_id text, p_user_email text default null, p_project_id text default null ) returns table ( id uuid, project_id uuid, user_id text, title text, columns_config jsonb, document_ids jsonb, workflow_id uuid, shared_with jsonb, created_at timestamptz, updated_at timestamptz, is_owner boolean, document_count integer ) language sql stable as $$ with accessible_projects as ( select p.id from public.projects p where p.user_id = p_user_id or ( coalesce(p_user_email, '') <> '' and p.user_id <> p_user_id and p.shared_with @> jsonb_build_array(p_user_email) ) ), visible_reviews as ( select tr.* from public.tabular_reviews tr where (p_project_id is null or tr.project_id::text = p_project_id) and ( p_project_id is null or exists ( select 1 from accessible_projects ap where ap.id::text = p_project_id ) ) and ( tr.user_id = p_user_id or ( tr.project_id in (select ap.id from accessible_projects ap) and tr.user_id <> p_user_id ) or ( p_project_id is null and coalesce(p_user_email, '') <> '' and tr.user_id <> p_user_id and tr.shared_with @> jsonb_build_array(p_user_email) ) ) ), cell_document_counts as ( select tc.review_id, count(distinct tc.document_id)::integer as document_count from public.tabular_cells tc where tc.review_id in (select vr.id from visible_reviews vr) group by tc.review_id ) select vr.id, vr.project_id, vr.user_id, vr.title, vr.columns_config, vr.document_ids, vr.workflow_id, vr.shared_with, vr.created_at, vr.updated_at, vr.user_id = p_user_id as is_owner, case when jsonb_typeof(vr.document_ids) = 'array' then ( select count(distinct doc_id.value)::integer from jsonb_array_elements_text(vr.document_ids) as doc_id(value) ) else coalesce(cdc.document_count, 0) end as document_count from visible_reviews vr left join cell_document_counts cdc on cdc.review_id = vr.id order by vr.created_at desc; $$;