230 lines
8.9 KiB
PL/PgSQL
230 lines
8.9 KiB
PL/PgSQL
-- 0001: Initial Cognis baseline schema
|
|
-- This file is intentionally idempotent enough to be retried after a failed SQL Editor run.
|
|
|
|
-- Enable necessary extensions
|
|
create extension if not exists "uuid-ossp";
|
|
|
|
-- 1. Create journals table
|
|
create table if not exists public.journals (
|
|
id uuid default uuid_generate_v4() primary key,
|
|
user_id uuid references auth.users(id) on delete cascade not null,
|
|
date timestamp with time zone default timezone('utc'::text, now()) not null,
|
|
mood text not null,
|
|
energy smallint not null,
|
|
content text not null,
|
|
ai_tags text[] default array[]::text[],
|
|
ai_sentiment_score numeric,
|
|
ai_summary text,
|
|
ai_reflection text,
|
|
analysis_status text default 'pending'::text,
|
|
created_at timestamp with time zone default timezone('utc'::text, now()) not null,
|
|
updated_at timestamp with time zone default timezone('utc'::text, now()) not null
|
|
);
|
|
|
|
-- 2. Create tasks table
|
|
create table if not exists public.tasks (
|
|
id uuid default uuid_generate_v4() primary key,
|
|
user_id uuid references auth.users(id) on delete cascade not null,
|
|
date timestamp with time zone default timezone('utc'::text, now()) not null,
|
|
title text not null,
|
|
description text,
|
|
status text default 'todo'::text,
|
|
ai_generated boolean default false,
|
|
source_journal_id uuid references public.journals(id) on delete set null,
|
|
created_at timestamp with time zone default timezone('utc'::text, now()) not null,
|
|
updated_at timestamp with time zone default timezone('utc'::text, now()) not null
|
|
);
|
|
|
|
-- 3. Create chat_sessions table
|
|
create table if not exists public.chat_sessions (
|
|
id uuid default uuid_generate_v4() primary key,
|
|
user_id uuid references auth.users(id) on delete cascade not null,
|
|
title text not null,
|
|
created_at timestamp with time zone default timezone('utc'::text, now()) not null,
|
|
updated_at timestamp with time zone default timezone('utc'::text, now()) not null
|
|
);
|
|
|
|
-- 4. Create chat_messages table
|
|
create table if not exists public.chat_messages (
|
|
id uuid default uuid_generate_v4() primary key,
|
|
session_id uuid references public.chat_sessions(id) on delete cascade not null,
|
|
role text not null,
|
|
content text not null,
|
|
context_journal_ids uuid[] default array[]::uuid[],
|
|
created_at timestamp with time zone default timezone('utc'::text, now()) not null
|
|
);
|
|
|
|
-- 5. Create profiles table
|
|
create table if not exists public.profiles (
|
|
id uuid references auth.users(id) on delete cascade primary key,
|
|
first_name text,
|
|
last_name text,
|
|
avatar_url text,
|
|
updated_at timestamp with time zone default timezone('utc'::text, now()) not null
|
|
);
|
|
|
|
-- RLS (Row Level Security)
|
|
alter table public.journals enable row level security;
|
|
alter table public.tasks enable row level security;
|
|
alter table public.chat_sessions enable row level security;
|
|
alter table public.chat_messages enable row level security;
|
|
alter table public.profiles enable row level security;
|
|
|
|
-- Journals policies
|
|
drop policy if exists "Users can view their own journals." on public.journals;
|
|
create policy "Users can view their own journals." on public.journals
|
|
for select using (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can insert their own journals." on public.journals;
|
|
create policy "Users can insert their own journals." on public.journals
|
|
for insert with check (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can update their own journals." on public.journals;
|
|
create policy "Users can update their own journals." on public.journals
|
|
for update using (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can delete their own journals." on public.journals;
|
|
create policy "Users can delete their own journals." on public.journals
|
|
for delete using (auth.uid() = user_id);
|
|
|
|
-- Tasks policies
|
|
drop policy if exists "Users can view their own tasks." on public.tasks;
|
|
create policy "Users can view their own tasks." on public.tasks
|
|
for select using (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can insert their own tasks." on public.tasks;
|
|
create policy "Users can insert their own tasks." on public.tasks
|
|
for insert with check (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can update their own tasks." on public.tasks;
|
|
create policy "Users can update their own tasks." on public.tasks
|
|
for update using (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can delete their own tasks." on public.tasks;
|
|
create policy "Users can delete their own tasks." on public.tasks
|
|
for delete using (auth.uid() = user_id);
|
|
|
|
-- Chat sessions policies
|
|
drop policy if exists "Users can view their own chat sessions." on public.chat_sessions;
|
|
create policy "Users can view their own chat sessions." on public.chat_sessions
|
|
for select using (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can insert their own chat sessions." on public.chat_sessions;
|
|
create policy "Users can insert their own chat sessions." on public.chat_sessions
|
|
for insert with check (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can update their own chat sessions." on public.chat_sessions;
|
|
create policy "Users can update their own chat sessions." on public.chat_sessions
|
|
for update using (auth.uid() = user_id);
|
|
|
|
drop policy if exists "Users can delete their own chat sessions." on public.chat_sessions;
|
|
create policy "Users can delete their own chat sessions." on public.chat_sessions
|
|
for delete using (auth.uid() = user_id);
|
|
|
|
-- Chat messages policies
|
|
drop policy if exists "Users can view their own chat messages." on public.chat_messages;
|
|
create policy "Users can view their own chat messages." on public.chat_messages
|
|
for select using (
|
|
exists (
|
|
select 1 from public.chat_sessions
|
|
where chat_sessions.id = chat_messages.session_id
|
|
and chat_sessions.user_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
drop policy if exists "Users can insert their own chat messages." on public.chat_messages;
|
|
create policy "Users can insert their own chat messages." on public.chat_messages
|
|
for insert with check (
|
|
exists (
|
|
select 1 from public.chat_sessions
|
|
where chat_sessions.id = session_id
|
|
and chat_sessions.user_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
drop policy if exists "Users can update their own chat messages." on public.chat_messages;
|
|
create policy "Users can update their own chat messages." on public.chat_messages
|
|
for update using (
|
|
exists (
|
|
select 1 from public.chat_sessions
|
|
where chat_sessions.id = session_id
|
|
and chat_sessions.user_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
drop policy if exists "Users can delete their own chat messages." on public.chat_messages;
|
|
create policy "Users can delete their own chat messages." on public.chat_messages
|
|
for delete using (
|
|
exists (
|
|
select 1 from public.chat_sessions
|
|
where chat_sessions.id = session_id
|
|
and chat_sessions.user_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
-- Profiles policies
|
|
drop policy if exists "Users can view their own profile." on public.profiles;
|
|
create policy "Users can view their own profile." on public.profiles
|
|
for select using (auth.uid() = id);
|
|
|
|
drop policy if exists "Users can insert their own profile." on public.profiles;
|
|
create policy "Users can insert their own profile." on public.profiles
|
|
for insert with check (auth.uid() = id);
|
|
|
|
drop policy if exists "Users can update their own profile." on public.profiles;
|
|
create policy "Users can update their own profile." on public.profiles
|
|
for update using (auth.uid() = id);
|
|
|
|
-- Function to handle new user signup
|
|
create or replace function public.handle_new_user()
|
|
returns trigger as $$
|
|
begin
|
|
insert into public.profiles (id, first_name, last_name, avatar_url)
|
|
values (new.id, '', '', '')
|
|
on conflict (id) do nothing;
|
|
|
|
return new;
|
|
end;
|
|
$$ language plpgsql security definer;
|
|
|
|
-- Trigger to automatically create profile on signup
|
|
drop trigger if exists on_auth_user_created on auth.users;
|
|
|
|
create trigger on_auth_user_created
|
|
after insert on auth.users
|
|
for each row execute procedure public.handle_new_user();
|
|
|
|
-- Setup storage bucket for avatars
|
|
insert into storage.buckets (id, name, public)
|
|
values ('avatars', 'avatars', true)
|
|
on conflict (id) do nothing;
|
|
|
|
drop policy if exists "Avatar images are publicly accessible." on storage.objects;
|
|
create policy "Avatar images are publicly accessible."
|
|
on storage.objects for select
|
|
using (bucket_id = 'avatars');
|
|
|
|
drop policy if exists "Users can upload an avatar." on storage.objects;
|
|
create policy "Users can upload an avatar."
|
|
on storage.objects for insert
|
|
with check (
|
|
bucket_id = 'avatars'
|
|
and auth.uid()::text = (storage.foldername(name))[1]
|
|
);
|
|
|
|
drop policy if exists "Users can update their own avatar." on storage.objects;
|
|
create policy "Users can update their own avatar."
|
|
on storage.objects for update
|
|
using (
|
|
bucket_id = 'avatars'
|
|
and auth.uid()::text = (storage.foldername(name))[1]
|
|
);
|
|
|
|
drop policy if exists "Users can delete their own avatar." on storage.objects;
|
|
create policy "Users can delete their own avatar."
|
|
on storage.objects for delete
|
|
using (
|
|
bucket_id = 'avatars'
|
|
and auth.uid()::text = (storage.foldername(name))[1]
|
|
);
|