-
Notifications
You must be signed in to change notification settings - Fork 0
Database
Thorben edited this page Mar 10, 2023
·
15 revisions
TODO: Add file which contains the statements to setup the database in an Supabase-environment
CREATE OR REPLACE
VIEW "AllTimeExpenses"
AS SELECT
SUM(transactions.amount),
json_build_object('id', categories.id,'name',categories.name, 'description', categories.description) as category,
transactions.created_by
FROM
transactions
INNER JOIN categories
ON categories.id = transactions.category
AND transactions.amount < 0
AND transactions.date::DATE <= now()::DATE
GROUP BY
categories.id,
transactions.created_by;
CREATE OR REPLACE
VIEW "AllTimeIncome"
AS SELECT
SUM(transactions.amount),
json_build_object('id', categories.id,'name',categories.name, 'description', categories.description) as category,
transactions.created_by
FROM
transactions
INNER JOIN categories
ON categories.id = transactions.category
AND transactions.amount > 0
AND transactions.date::DATE <= now()::DATE
GROUP BY
categories.id,
transactions.created_by;
CREATE OR REPLACE
VIEW "BudgetProgress"
AS SELECT
budget.id,
json_build_object('id', categories.id,'name',categories.name, 'description', categories.description) as category,
budget.budget,
(SELECT
SUM(transactions.amount)
FROM
transactions
WHERE
transactions.amount < 0
AND
transactions.date::DATE <= now()::DATE
AND
extract(month FROM transactions.date) = extract(month FROM now())
AND
extract(year FROM transactions.date) = extract(year FROM now())
AND transactions.category = budget.category
) as "currentlySpent",
budget.created_by,
budget.inserted_at,
budget.updated_at
FROM budget
LEFT JOIN categories
ON categories.id = budget.category;
CREATE OR REPLACE
VIEW "CurrentMonthExpenses"
AS SELECT
SUM(transactions.amount),
json_build_object('id', categories.id,'name',categories.name, 'description', categories.description) as category,
transactions.created_by
FROM
transactions
INNER JOIN categories
ON categories.id = transactions.category
AND
transactions.amount < 0
AND
transactions.date::DATE <= now()::DATE
AND
extract(month FROM transactions.date) = extract(month FROM now())
AND
extract(year FROM transactions.date) = extract(year FROM now())
GROUP BY
categories.id,
transactions.created_by;
CREATE OR REPLACE
VIEW "CurrentMonthIncome"
AS SELECT
SUM(transactions.amount),
json_build_object('id', categories.id,'name',categories.name, 'description', categories.description) as category,
transactions.created_by
FROM
transactions
INNER JOIN categories
ON categories.id = transactions.category
AND
transactions.amount > 0
AND
transactions.date::DATE <= now()::DATE
AND
extract(month FROM transactions.date) = extract(month FROM now())
AND
extract(year FROM transactions.date) = extract(year FROM now())
GROUP BY
categories.id,
transactions.created_by;
CREATE OR REPLACE
VIEW "DailyIncome"
AS SELECT
transactions.date::DATE,
sum(transactions.amount),
transactions.created_by
FROM transactions
WHERE transactions.amount > 0
AND transactions.date::DATE <= now()::DATE
GROUP BY 1, transactions.created_by
ORDER BY transactions.date::DATE ASC;
CREATE OR REPLACE
VIEW "DailyExpense"
AS SELECT
transactions.date::DATE,
sum(transactions.amount),
transactions.created_by
FROM transactions
WHERE transactions.amount < 0
AND transactions.date::DATE <= now()::DATE
GROUP BY 1, transactions.created_by
ORDER BY transactions.date::DATE ASC;
CREATE OR REPLACE FUNCTION get_daily_transactions(start_date date, end_date date, requested_data text)
RETURNS TABLE(date date, amount double precision)
LANGUAGE sql
AS $$
SELECT
dates.transaction_date as date,
(SELECT COALESCE(SUM(t.amount), 0)
FROM transactions t
WHERE date_trunc('day', t.date) = dates.transaction_date
AND requested_data = TRIM(requested_data)
AND (
(requested_data = 'INCOME' AND t.amount >= 0)
OR (requested_data = 'SPENDINGS' AND t.amount <= 0)
OR (requested_data = 'BALANCE')
))
FROM (
SELECT generate_series(start_date, end_date, '1 day') AS transaction_date
) AS dates
GROUP BY
dates.transaction_date
ORDER BY
dates.transaction_date ASC;
$$;
Possible type values are "COUNT" | "EARNINGS" | "SPENDINGS"
create function get_category_stats(type text)
returns TABLE(value double precision, category jsonb)
language sql
as
$$
SELECT
CASE
WHEN type = 'COUNT' THEN COUNT(t."category")
WHEN type = 'EARNINGS' OR type = 'SPENDINGS' THEN SUM(t."amount")
END "value",
json_build_object('id', "categories".id,'name',"categories".name, 'description', "categories".description) as "category"
FROM transactions t
LEFT JOIN "categories"
ON "categories".id = t."category"
WHERE
(type = 'EARNINGS' AND t.amount > 0) OR (type = 'SPENDINGS' AND t.amount < 0) OR (type = 'COUNT')
GROUP BY
t."category", "categories".id;
$$;
Possible type values are "COUNT" | "EARNINGS" | "SPENDINGS"
create function get_pm_stats(type text)
returns TABLE(value double precision, "paymentMethod" jsonb)
language sql
as
$$
SELECT
CASE
WHEN type = 'COUNT' THEN COUNT(t."paymentMethod")
WHEN type = 'EARNINGS' OR type = 'SPENDINGS' THEN SUM(t."amount")
END "value",
json_build_object('id', "paymentMethods".id,'name',"paymentMethods".name, 'address', "paymentMethods".address, 'provider', "paymentMethods".provider, 'description', "paymentMethods".description) as "paymentMethod"
FROM transactions t
LEFT JOIN "paymentMethods"
ON "paymentMethods".id = t."paymentMethod"
WHERE
(type = 'EARNINGS' AND t.amount > 0) OR (type = 'SPENDINGS' AND t.amount < 0) OR (type = 'COUNT')
GROUP BY
t."paymentMethod", "paymentMethods".id;
$$;
create function get_monthly_balance(months bigint)
returns TABLE(year bigint, month bigint, sum double precision)
language sql
as
$$
SELECT
extract(YEAR FROM transactions.date) as Year,
extract(MONTH FROM transactions.date) as Month,
SUM(transactions.amount)
FROM
transactions
GROUP BY
extract(MONTH FROM transactions.date),
extract(YEAR FROM transactions.date)
ORDER BY
extract(YEAR FROM transactions.date) DESC,
extract(MONTH FROM transactions.date) DESC
LIMIT months;
$$;
create function get_monthly_balance_avg(months bigint)
returns double precision
language sql
as
$$
SELECT avg(sum) FROM get_monthly_balance(months);
$$;
CREATE OR REPLACE
FUNCTION "getIncome"("userId" uuid, "startDate" Date, "endDate" Date)
RETURNS TABLE (
sum float8,
category json,
created_by uuid
)
as $$
SELECT
SUM(transactions.amount),
json_build_object('id', categories.id,'name',categories.name, 'description', categories.description) as category,
transactions.created_by
FROM
transactions
INNER JOIN categories
ON categories.id = transactions.category
AND
transactions.amount > 0
AND
transactions.date::DATE >= "startDate"
AND
transactions.date::DATE <= "endDate"
WHERE
transactions.created_by = "userId"
GROUP BY
categories.id,
transactions.created_by;
$$ language sql;
CREATE OR REPLACE
FUNCTION "getExpense"("userId" uuid, "startDate" Date, "endDate" Date)
RETURNS TABLE (
sum float8,
category json,
created_by uuid
)
as $$
SELECT
SUM(transactions.amount),
json_build_object('id', categories.id,'name',categories.name, 'description', categories.description) as category,
transactions.created_by
FROM
transactions
INNER JOIN categories
ON categories.id = transactions.category
AND
transactions.amount < 0
AND
transactions.date::DATE >= "startDate"
AND
transactions.date::DATE <= "endDate"
WHERE
transactions.created_by = "userId"
GROUP BY
categories.id,
transactions.created_by;
$$ language sql;
Column | Type | Description |
---|---|---|
id |
int8 |
PK |
category |
int8 |
FK category -> categories.id
|
paymentMethod |
int8 |
FK category -> categories.id
|
receiver |
text |
|
amount |
float8 |
|
description |
text or null |
|
date |
timestampz |
|
created_by |
uuid |
FK created_by -> auth.users.id
|
inserted_at |
timestampz |
|
updated_at |
timestampz |
create table transactions (
id bigint generated by default as identity primary key,
category bigint references public.categories not null,
paymentMethod bigint references public."paymentMethods" not null,
receiver text not null,
description text,
amount float not null,
date timestamp with time zone not null,
created_by uuid references auth.users not null,
inserted_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
);
Enable
alter table "public"."transactions"
enable row level security;
All (for authentificated)
Used for the web-app
CREATE POLICY "Users can handle their transactions." ON "public"."transactions"
AS PERMISSIVE FOR ALL
TO public
USING ((uid() = created_by))
WITH CHECK ((uid() = created_by))
All (all, insert alone won't work)
Used for the subscription-service
CREATE POLICY "Subscription-Service can insert transactions." ON "public"."transactions"
AS PERMISSIVE FOR ALL
TO authenticated
USING ((email() = 'EMAIL'::text))
WITH CHECK ((email() = 'EMAIL'::text))
Column | Type | Description |
---|---|---|
id |
int8 |
PK |
category |
int8 |
FK category -> categories.id
|
budget |
float8 |
|
created_by |
uuid |
FK created_by -> auth.users.id
|
inserted_at |
timestampz |
|
updated_at |
timestampz |
create table budget (
id bigint generated by default as identity primary key,
category bigint references public.categories not null,
budget float not null,
created_by uuid references auth.users not null,
inserted_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
);
Enable
alter table "public"."budget"
enable row level security;
All
CREATE POLICY "Users can handle their budget." ON "public"."transactions"
AS PERMISSIVE FOR ALL
TO public
USING ((uid() = created_by))
WITH CHECK ((uid() = created_by))
Column | Type | Description |
---|---|---|
id |
int8 |
PK |
category |
int8 |
FK category -> categories.id
|
paymentMethod |
int8 |
FK category -> categories.id
|
receiver |
text |
|
amount |
float8 |
|
description |
text or null |
|
execute_at |
int8 |
|
created_by |
uuid |
FK created_by -> auth.users.id
|
inserted_at |
timestampz |
|
updated_at |
timestampz |
create table subscriptions (
id bigint generated by default as identity primary key,
category bigint references public.categories not null,
paymentMethod bigint references public."paymentMethods" not null,
receiver text not null,
description text,
amount float not null,
execute_at bigint not null,
created_by uuid references auth.users not null,
inserted_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
);
Enable
alter table "public"."subscriptions"
enable row level security;
All (for authentificated)
Used for the app
CREATE POLICY "Authentificated users can handle their subscription." ON "public"."subscriptions"
AS PERMISSIVE FOR ALL
TO authenticated
USING ((uid() = created_by))
WITH CHECK ((uid() = created_by))
Select (for Subscription-Service)
Used for the subscription-service
CREATE POLICY "Subscription-Service can select subscriptions." ON "public"."subscriptions"
AS PERMISSIVE FOR SELECT
TO authenticated
USING ((email() = 'EMAIL'::text))
Column | Type | Description |
---|---|---|
id |
int8 |
PK |
name |
text |
|
description |
text or null |
|
created_by |
uuid |
FK created_by ->auth.users.id
|
inserted_at |
timestampz |
|
updated_at |
timestampz |
create table categories (
id int8 generated by default as identity primary key,
name text not null,
description text,
created_by uuid references auth.users not null,
inserted_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
);
Enable
alter table "public"."categories"
enable row level security;
All
CREATE POLICY "Users can handle their categories." ON "public"."categories"
AS PERMISSIVE FOR ALL
TO public
USING ((uid() = created_by))
WITH CHECK ((uid() = created_by))
Column | Type | Description |
---|---|---|
id |
int8 |
PK |
name |
text |
|
provider |
text |
|
address |
text |
|
description |
text or null |
|
created_by |
uuid |
FK created_by -> auth.users.id
|
inserted_at |
timestampz |
|
updated_at |
timestampz |
create table paymentMethods (
id int8 generated by default as identity primary key,
name text not null,
provider text not null,
address text not null,
description text,
created_by uuid references auth.users not null,
inserted_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
);
Enable
alter table "public"."paymentMethods"
enable row level security;
All
CREATE POLICY "Users can handle their payment-methods." ON "public"."paymentMethods"
AS PERMISSIVE FOR ALL
TO public
USING ((uid() = created_by))
WITH CHECK ((uid() = created_by))
Column | Type | Description |
---|---|---|
id |
int8 |
PK |
rating |
float4 |
|
text |
text or null |
|
share |
boolean |
Default false
|
author |
uuid or null |
Default null
|
inserted_at |
timestampz |
create table feedback (
id bigint generated by default as identity primary key,
rating float4 not null,
text text,
share boolean default false,
author uuid default null,
inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
);