Skip to content

Commit

Permalink
chore: Supabase migrations (#496)
Browse files Browse the repository at this point in the history
* chore: migrate the PSQL database during startup
  • Loading branch information
YrrepNoj authored May 10, 2024
1 parent ebe4fde commit 86ed880
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 3 deletions.
13 changes: 13 additions & 0 deletions packages/supabase/bitnami-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,23 @@ postgresql:
enabled: ###ZARF_VAR_ENABLE_POSTGRES###
image:
tag: 15.1.1-debian-12-r24
debug: true
primary:
resourcesPreset: "none"
podLabels:
sidecar.istio.io/inject: "false"
initdb:
scripts:
0000000000000000_migrate.sh: |
###ZARF_VAR_MIGRATION_SCRIPT###
20240322174520_api_sql_schema.sql: |
###ZARF_VAR_API_SQL_SCHEMA###
20240322174521_ui_sql_schema.sql: |
###ZARF_VAR_UI_SQL_SCHEMA###
commonAnnotations:
helm.sh/resource-policy: keep
## @param postgresql.postgresqlSharedPreloadLibraries Set the shared_preload_libraries parameter in postgresql.conf
Expand Down
18 changes: 18 additions & 0 deletions packages/supabase/migrations/20240322174520_api_sql_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- Create a table to store the OpenAI File Objects
create table
file_objects (
id uuid primary key DEFAULT uuid_generate_v4(),
bytes int,
created_at bigint,
filename text,
object text,
purpose text,
status text,
status_details text
);

-- storage bucket for the files
insert into storage.buckets
(id, name, public)
values
('file_bucket', 'files', true);
188 changes: 188 additions & 0 deletions packages/supabase/migrations/20240322174521_ui_sql_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
create table conversations (
id uuid primary key DEFAULT uuid_generate_v4(),
user_id uuid references auth.users not null,
label text,
inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
);


create table messages (
id uuid primary key DEFAULT uuid_generate_v4(),
user_id uuid references auth.users not null,
conversation_id uuid references conversations on delete cascade not null,
role text check (role in ('system', 'user', 'assistant', 'function', 'data', 'tool')),
content text,
inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
);

-- Create a table for public profiles
create table profiles (
id uuid references auth.users not null primary key,
updated_at timestamp with time zone,
username text unique,
full_name text,
avatar_url text,
website text,

constraint username_length check (char_length(username) >= 3)
);

alter table conversations enable row level security;

alter table messages enable row level security;

alter table profiles enable row level security;

-- Policies for conversations
create policy "Individuals can create conversations." on conversations for
insert with check (auth.uid() = user_id);
create policy "Individuals can view their own conversations. " on conversations for
select using (auth.uid() = user_id);
create policy "Individuals can update their own conversations." on conversations for
update using (auth.uid() = user_id);
create policy "Individuals can delete their own conversations." on conversations for
delete using (auth.uid() = user_id);

-- Policies for messages
create policy "Individuals can view their own messages." on messages for
select using (auth.uid() = user_id);
create policy "Individuals can create messages." on messages for
insert with check (auth.uid() = user_id);
create policy "Individuals can update their own messages." on messages for
update using (auth.uid() = user_id);
create policy "Individuals can delete their own messages." on messages for
delete using (auth.uid() = user_id);

-- Policies for profiles
create policy "Public profiles are viewable by everyone." on profiles
for select using (true);

create policy "Users can insert their own profile." on profiles
for insert with check (auth.uid() = id);

create policy "Users can update own profile." on profiles
for update using (auth.uid() = id);

-- Set up access controls for storage.
-- See https://supabase.com/docs/guides/storage/security/access-control#policy-examples for more details.
create policy "Avatar images are publicly accessible." on storage.objects
for select using (bucket_id = 'avatars');

create policy "Anyone can upload an avatar." on storage.objects
for insert with check (bucket_id = 'avatars');

create policy "Anyone can update their own avatar." on storage.objects
for update using (auth.uid() = owner) with check (bucket_id = 'avatars');


-- This trigger automatically creates a profile entry when a new user signs up via Supabase Auth.
-- See https://supabase.com/docs/guides/auth/managing-user-data#using-triggers for more details.
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, full_name, avatar_url)
values (new.id, new.raw_user_meta_data->>'full_name', new.raw_user_meta_data->>'avatar_url');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();

-- Set up Storage!
insert into storage.buckets (id, name)
values ('avatars', 'avatars');

alter table conversations enable row level security;

alter table messages enable row level security;

alter table profiles enable row level security;

-- Policies for conversations
create policy "Individuals can create conversations." on conversations for
insert with check (auth.uid() = user_id);
create policy "Individuals can view their own conversations. " on conversations for
select using (auth.uid() = user_id);
create policy "Individuals can update their own conversations." on conversations for
update using (auth.uid() = user_id);
create policy "Individuals can delete their own conversations." on conversations for
delete using (auth.uid() = user_id);

-- Policies for messages
create policy "Individuals can view their own messages." on messages for
select using (auth.uid() = user_id);
create policy "Individuals can create messages." on messages for
insert with check (auth.uid() = user_id);
create policy "Individuals can update their own messages." on messages for
update using (auth.uid() = user_id);
create policy "Individuals can delete their own messages." on messages for
delete using (auth.uid() = user_id);

-- Policies for profiles
create policy "Public profiles are viewable by everyone." on profiles
for select using (true);

create policy "Users can insert their own profile." on profiles
for insert with check (auth.uid() = id);

create policy "Users can update own profile." on profiles
for update using (auth.uid() = id);

-- Set up access controls for storage.
-- See https://supabase.com/docs/guides/storage/security/access-control#policy-examples for more details.
create policy "Avatar images are publicly accessible." on storage.objects
for select using (bucket_id = 'avatars');

create policy "Anyone can upload an avatar." on storage.objects
for insert with check (bucket_id = 'avatars');

create policy "Anyone can update their own avatar." on storage.objects
for update using (auth.uid() = owner) with check (bucket_id = 'avatars');


-- Policies for assistants
CREATE POLICY "Individuals can view their own assistants." ON assistants
FOR SELECT USING ((metadata ->> 'created_by') = auth.uid()::text);
create policy "Individuals can create assistants." on assistants for
insert with check ((metadata ->> 'created_by') = auth.uid()::text);
create policy "Individuals can update their own assistants." on assistants for
update using ((metadata ->> 'created_by') = auth.uid()::text);
create policy "Individuals can delete their own assistants." on assistants for
delete using ((metadata ->> 'created_by') = auth.uid()::text);


-- This trigger automatically creates a profile entry when a new user signs up via Supabase Auth.
-- See https://supabase.com/docs/guides/auth/managing-user-data#using-triggers for more details.
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, full_name, avatar_url)
values (new.id, new.raw_user_meta_data->>'full_name', new.raw_user_meta_data->>'avatar_url');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();

-- Set up Storage!
insert into storage.buckets (id, name)
values ('avatars', 'avatars');


CREATE TABLE Assistants (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
object text CHECK (object in ('assistant')),
name VARCHAR(255),
description VARCHAR(512),
model VARCHAR(255) NOT NULL,
instructions TEXT,
tools jsonb,
tool_resources jsonb,
metadata jsonb,
temperature FLOAT,
top_p FLOAT,
response_format jsonb,
created_at timestamp with time zone default timezone('utc'::text, now()) not null
);
43 changes: 43 additions & 0 deletions packages/supabase/migrations/migrate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash
# Copyright VMware, Inc.
# SPDX-License-Identifier: APACHE-2.0

# shellcheck disable=SC1090,SC1091
set -eu

. /opt/bitnami/scripts/libpostgresql.sh
. /opt/bitnami/scripts/postgresql-env.sh

##
## Script adapted from upstream migrate.sh
## https://github.com/supabase/postgres/blob/develop/migrations/db/migrate.sh
##

export PGDATABASE="${POSTGRESQL_DB:-postgres}"
export PGHOST="${POSTGRES_HOST:-localhost}"
export PGPORT="${POSTGRESQL_PORT_NUMBER:-5432}"
if [[ "$POSTGRESQL_USERNAME" = "postgres" ]]; then
export PGPASSWORD="${POSTGRESQL_PASSWORD:-}"
else
export PGPASSWORD="${POSTGRESQL_POSTGRES_PASSWORD:-}"
fi

for sql in /opt/bitnami/supabase-postgres/migrations/*.sql; do
echo "$0: running $sql"
psql -v ON_ERROR_STOP=1 --no-password --no-psqlrc -U postgres -f "$sql"
done

for sql in /opt/bitnami/supabase-postgres/migrations/db/init-scripts/*.sql; do
echo "$0: running $sql"
psql -v ON_ERROR_STOP=1 --no-password --no-psqlrc -U postgres -f "$sql"
done
echo "Configuring supabase_admin user"
psql -v ON_ERROR_STOP=1 --no-password --no-psqlrc -U postgres -c "ALTER USER supabase_admin WITH PASSWORD '$PGPASSWORD'"
# run migrations as super user - postgres user demoted in post-setup
for sql in /opt/bitnami/supabase-postgres/migrations/db/migrations/*.sql; do
echo "$0: running $sql"
psql -v ON_ERROR_STOP=1 --no-password --no-psqlrc -U supabase_admin -f "$sql"
done

# once done with everything, reset stats from init
psql -v ON_ERROR_STOP=1 --no-password --no-psqlrc -U supabase_admin -c 'SELECT extensions.pg_stat_statements_reset(); SELECT pg_stat_reset();' || true
26 changes: 23 additions & 3 deletions packages/supabase/zarf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ constants:
value: "https://keycloak.admin.uds.dev/realms/uds"

variables:
- name: UI_SQL_SCHEMA
type: file
default: "migrations/20240322174521_ui_sql_schema.sql"
autoIndent: true
- name: API_SQL_SCHEMA
type: file
default: "migrations/20240322174520_api_sql_schema.sql"
autoIndent: true
- name: MIGRATION_SCRIPT
type: file
default: "migrations/migrate.sh"
autoIndent: true

- name: ENABLE_AUTH
description: 'Enable Supabases built-in authentication and authorization parts'
default: "true"
Expand All @@ -32,10 +45,10 @@ variables:
default: "true"
- name: ENABLE_REST
description: 'Enable the autogenerated high level rest API for interacting with the database'
default: "true"
default: "true"
- name: ENABLE_STORAGE
description: 'Enable the Supabase object store'
default: "true"
default: "true"
- name: ENABLE_STUDIO
description: 'Enable the dashboard for managing Supabase, this dashboard depends on and sits atop other Supabase components'
default: "true"
Expand Down Expand Up @@ -95,6 +108,13 @@ components:
- docker.io/bitnami/supabase-storage:0.48.4-debian-12-r0
- docker.io/bitnami/supabase-studio:0.24.3-debian-12-r0
- docker.io/bitnami/kong:3.6.1-debian-12-r13
files:
- source: migrations/migrate.sh
target: migrations/migrate.sh
- source: migrations/20240322174521_ui_sql_schema.sql
target: migrations/20240322174521_ui_sql_schema.sql
- source: migrations/20240322174520_api_sql_schema.sql
target: migrations/20240322174520_api_sql_schema.sql
- name: supabase-post-process
description: "Perform necessary post processing here"
required: true
Expand All @@ -114,4 +134,4 @@ components:
- name: supabase-manifests
namespace: leapfrogai
files:
- "manifests/declarative-conf-configmap.yaml"
- "manifests/declarative-conf-configmap.yaml"

0 comments on commit 86ed880

Please sign in to comment.