Activos now supports multi-file/folder upload to private Storage (PDF, Excel, CSV, images, ZIP, etc.) with per-tenant folders. Co-authored-by: Cursor <cursoragent@cursor.com>
65 lines
2.1 KiB
SQL
65 lines
2.1 KiB
SQL
-- File assets library (validated uploads per tenant)
|
|
-- Idempotent.
|
|
|
|
create table if not exists public.asset_files (
|
|
id uuid primary key default gen_random_uuid(),
|
|
tenant_id uuid not null references public.tenants(id) on delete cascade,
|
|
title text not null,
|
|
folder text not null default '',
|
|
file_name text not null,
|
|
mime_type text,
|
|
bytes bigint,
|
|
storage_path text not null,
|
|
sha256 text,
|
|
status text not null default 'approved'
|
|
check (status in ('approved', 'archived')),
|
|
created_by uuid references auth.users(id),
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
create index if not exists asset_files_tenant_folder_idx
|
|
on public.asset_files (tenant_id, folder, created_at desc);
|
|
|
|
alter table public.asset_files enable row level security;
|
|
|
|
drop policy if exists asset_files_tenant_select on public.asset_files;
|
|
drop policy if exists asset_files_tenant_insert on public.asset_files;
|
|
drop policy if exists asset_files_tenant_update on public.asset_files;
|
|
drop policy if exists asset_files_tenant_delete on public.asset_files;
|
|
|
|
create policy asset_files_tenant_select on public.asset_files
|
|
for select using (
|
|
tenant_id::text = coalesce(
|
|
auth.jwt() -> 'app_metadata' ->> 'tenant_id',
|
|
auth.jwt() -> 'user_metadata' ->> 'tenant_id'
|
|
)
|
|
);
|
|
|
|
create policy asset_files_tenant_insert on public.asset_files
|
|
for insert with check (
|
|
tenant_id::text = coalesce(
|
|
auth.jwt() -> 'app_metadata' ->> 'tenant_id',
|
|
auth.jwt() -> 'user_metadata' ->> 'tenant_id'
|
|
)
|
|
);
|
|
|
|
create policy asset_files_tenant_update on public.asset_files
|
|
for update using (
|
|
tenant_id::text = coalesce(
|
|
auth.jwt() -> 'app_metadata' ->> 'tenant_id',
|
|
auth.jwt() -> 'user_metadata' ->> 'tenant_id'
|
|
)
|
|
);
|
|
|
|
create policy asset_files_tenant_delete on public.asset_files
|
|
for delete using (
|
|
tenant_id::text = coalesce(
|
|
auth.jwt() -> 'app_metadata' ->> 'tenant_id',
|
|
auth.jwt() -> 'user_metadata' ->> 'tenant_id'
|
|
)
|
|
);
|
|
|
|
-- Private bucket (created via API if missing). Policies for storage.objects:
|
|
-- path layout: {tenant_id}/{optional/folder/}{uuid}_{filename}
|