Skip to content

Commit

Permalink
Merge pull request midday-ai#165 from midday-ai/feature/local-develop…
Browse files Browse the repository at this point in the history
…ment-v1

Documentation
  • Loading branch information
pontusab authored Jun 24, 2024
2 parents 4176505 + c036704 commit 48676e8
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 20 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI
env:
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_SECRET: ${{ secrets.GOOGLE_SECRET_WEBSITE }}

# on:
# pull_request:
# workflow_dispatch:

jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/api

steps:
- uses: actions/checkout@v3
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Start Supabase local development setup
run: supabase db start
- name: Verify generated types are checked in
run: |
supabase gen types typescript --local > types.gen.ts
if ! git diff --ignore-space-at-eol --exit-code --quiet types.gen.ts; then
echo "Detected uncommitted changes after build. See status below:"
git diff
exit 1
fi
32 changes: 31 additions & 1 deletion apps/api/supabase/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
project_id = "pytddvqiozwrhfbwqazp"

[api]
enabled = true
port = 54321
schemas = ["public", "storage"]
extra_search_path = ["public", "extensions"]
max_rows = 1000000

[auth]
site_url = "http://localhost:3001"
additional_redirect_urls = ["https://localhost:3001", "http://localhost:54321/auth/v1/callback"]
jwt_expiry = 36000

[db]
port = 54322

[studio]
port = 54323

[auth.external.google]
enabled = true
client_id = "env(GOOGLE_CLIENT_ID)"
secret = "env(GOOGLE_SECRET)"
secret = "env(GOOGLE_SECRET)"
redirect_uri = "http://localhost:54321/auth/v1/callback"

[auth.email]
double_confirm_changes = true
enable_confirmations = true
enable_signup = true

[analytics]
enabled = true
port = 54327
vector_port = 54328
backend = "postgres"
5 changes: 0 additions & 5 deletions apps/api/supabase/migrations/20240617143056_remote_schema.sql

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ SET row_security = off;

CREATE EXTENSION IF NOT EXISTS "pg_net" WITH SCHEMA "extensions";

CREATE EXTENSION IF NOT EXISTS "pgsodium" WITH SCHEMA "pgsodium";

CREATE SCHEMA IF NOT EXISTS "private";

ALTER SCHEMA "private" OWNER TO "postgres";
Expand All @@ -26,12 +28,24 @@ CREATE EXTENSION IF NOT EXISTS "pgcrypto" WITH SCHEMA "extensions";

CREATE EXTENSION IF NOT EXISTS "pgjwt" WITH SCHEMA "extensions";

CREATE EXTENSION IF NOT EXISTS "supabase_vault" WITH SCHEMA "vault";

CREATE EXTENSION IF NOT EXISTS "unaccent" WITH SCHEMA "public";

CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA "extensions";

CREATE EXTENSION IF NOT EXISTS "vector" WITH SCHEMA "extensions";

CREATE TYPE "public"."account_type" AS ENUM (
'depository',
'credit',
'other_asset',
'loan',
'other_liability'
);

ALTER TYPE "public"."account_type" OWNER TO "postgres";

CREATE TYPE "public"."bankProviders" AS ENUM (
'gocardless',
'plaid',
Expand Down Expand Up @@ -216,6 +230,22 @@ $_$;

ALTER FUNCTION "public"."calculated_vat"("public"."transactions") OWNER TO "postgres";

CREATE OR REPLACE FUNCTION "public"."create_team"("name" character varying) RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
declare
new_team_id uuid;
begin
insert into teams (name) values (name) returning id into new_team_id;
insert into users_on_team (user_id, team_id, role) values (auth.uid(), new_team_id, 'owner');

return new_team_id;
end;
$$;

ALTER FUNCTION "public"."create_team"("name" character varying) OWNER TO "postgres";

CREATE OR REPLACE FUNCTION "public"."extract_product_names"("products_json" "json") RETURNS "text"
LANGUAGE "plpgsql" IMMUTABLE
AS $$
Expand All @@ -229,6 +259,19 @@ $$;

ALTER FUNCTION "public"."extract_product_names"("products_json" "json") OWNER TO "postgres";

CREATE OR REPLACE FUNCTION "public"."generate_hmac"("secret_key" "text", "message" "text") RETURNS "text"
LANGUAGE "plpgsql"
AS $$
DECLARE
hmac_result bytea;
BEGIN
hmac_result := extensions.hmac(message::bytea, secret_key::bytea, 'sha256');
RETURN encode(hmac_result, 'base64');
END;
$$;

ALTER FUNCTION "public"."generate_hmac"("secret_key" "text", "message" "text") OWNER TO "postgres";

CREATE OR REPLACE FUNCTION "public"."generate_id"("size" integer) RETURNS "text"
LANGUAGE "plpgsql"
AS $$
Expand Down Expand Up @@ -937,6 +980,62 @@ end;$$;

ALTER FUNCTION "public"."upsert_transaction_enrichment"() OWNER TO "postgres";

CREATE OR REPLACE FUNCTION "public"."webhook"() RETURNS "trigger"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
DECLARE
url text;
secret text;
payload jsonb;
request_id bigint;
signature text;
path text;
BEGIN
-- Extract the first item from TG_ARGV as path
path = TG_ARGV[0];

-- Get the webhook URL and secret from the vault
SELECT decrypted_secret INTO url FROM vault.decrypted_secrets WHERE name = 'WEBHOOK_ENDPOINT' LIMIT 1;
SELECT decrypted_secret INTO secret FROM vault.decrypted_secrets WHERE name = 'WEBHOOK_SECRET' LIMIT 1;

-- Generate the payload
payload = jsonb_build_object(
'old_record', old,
'record', new,
'type', tg_op,
'table', tg_table_name,
'schema', tg_table_schema
);

-- Generate the signature
signature = generate_hmac(secret, payload::text);

-- Send the webhook request
SELECT http_post
INTO request_id
FROM
net.http_post(
url := url || '/' || path,
body := payload,
headers := jsonb_build_object(
'Content-Type', 'application/json',
'X-Supabase-Signature', signature
),
timeout_milliseconds := 3000
);

-- Insert the request ID into the Supabase hooks table
INSERT INTO supabase_functions.hooks
(hook_table_id, hook_name, request_id)
VALUES (tg_relid, tg_name, request_id);

RETURN new;
END;
$$;

ALTER FUNCTION "public"."webhook"() OWNER TO "postgres";

CREATE TABLE IF NOT EXISTS "public"."bank_accounts" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
Expand All @@ -949,7 +1048,8 @@ CREATE TABLE IF NOT EXISTS "public"."bank_accounts" (
"enabled" boolean DEFAULT true NOT NULL,
"account_id" "text" NOT NULL,
"balance" numeric DEFAULT '0'::numeric,
"manual" boolean DEFAULT false
"manual" boolean DEFAULT false,
"type" "public"."account_type"
);

ALTER TABLE "public"."bank_accounts" OWNER TO "postgres";
Expand Down Expand Up @@ -1179,13 +1279,13 @@ CREATE INDEX "transactions_team_id_idx" ON "public"."transactions" USING "btree"

CREATE INDEX "users_on_team_team_id_idx" ON "public"."users_on_team" USING "btree" ("team_id");

CREATE OR REPLACE TRIGGER "embed_category" AFTER INSERT OR UPDATE OF "name" ON "public"."transaction_categories" FOR EACH ROW WHEN (("new"."system" = false)) EXECUTE FUNCTION "supabase_functions"."http_request"('https://pytddvqiozwrhfbwqazp.supabase.co/functions/v1/generate-category-embedding', 'POST', '{"Content-type":"application/json","Authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InB5dGRkdnFpb3p3cmhmYndxYXpwIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTY1ODM2MzgsImV4cCI6MjAxMjE1OTYzOH0.ICOeoR7nVt1bxKtTYfo1xe4m2l3d2CMmqh1kKZAb35c"}', '{}', '5000');
CREATE OR REPLACE TRIGGER "embed_category" AFTER INSERT OR UPDATE ON "public"."transaction_categories" FOR EACH ROW EXECUTE FUNCTION "supabase_functions"."http_request"('https://pytddvqiozwrhfbwqazp.supabase.co/functions/v1/generate-category-embedding', 'POST', '{"Content-type":"application/json"}', '{}', '5000');

CREATE OR REPLACE TRIGGER "generate_category_slug" BEFORE INSERT ON "public"."transaction_categories" FOR EACH ROW EXECUTE FUNCTION "public"."generate_slug_from_name"();

CREATE OR REPLACE TRIGGER "insert_system_categories_trigger" AFTER INSERT ON "public"."teams" FOR EACH ROW EXECUTE FUNCTION "public"."insert_system_categories"();

CREATE OR REPLACE TRIGGER "match_transaction" AFTER INSERT ON "public"."transactions" FOR EACH ROW EXECUTE FUNCTION "supabase_functions"."http_request"('https://app.midday.ai/api/webooks/inbox/match', 'POST', '{"Content-type":"application/json","x-api-key":"szlv1yTFbgV7rmwchh2r3Medq28ZbDMF4QiPKE2Mr5fGADKTl1xTH1vKjxLf2vsj"}', '{}', '1000');
CREATE OR REPLACE TRIGGER "match_transaction" AFTER INSERT ON "public"."transactions" FOR EACH ROW EXECUTE FUNCTION "public"."webhook"('webhook/inbox/match');

CREATE OR REPLACE TRIGGER "on_updated_transaction_category" AFTER UPDATE OF "category_slug" ON "public"."transactions" FOR EACH ROW EXECUTE FUNCTION "public"."upsert_transaction_enrichment"();

Expand Down Expand Up @@ -1308,11 +1408,7 @@ CREATE POLICY "Enable insert for authenticated users only" ON "public"."transact

CREATE POLICY "Enable insert for authenticated users only" ON "public"."users_on_team" FOR INSERT TO "authenticated" WITH CHECK (true);

CREATE POLICY "Enable select for authenticated users only" ON "public"."teams" FOR SELECT TO "authenticated" USING (true);

CREATE POLICY "Enable select for authenticated users only" ON "public"."transaction_enrichments" FOR SELECT TO "authenticated" USING (true);

CREATE POLICY "Enable select for authenticated users only" ON "public"."users_on_team" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "Enable read access for all users" ON "public"."users_on_team" FOR SELECT USING (true);

CREATE POLICY "Enable select for users based on email" ON "public"."user_invites" FOR SELECT USING ((("auth"."jwt"() ->> 'email'::"text") = "email"));

Expand Down Expand Up @@ -1388,12 +1484,12 @@ CREATE POLICY "User Invites can be updated by a member of the team" ON "public".

CREATE POLICY "Users can insert their own profile." ON "public"."users" FOR INSERT WITH CHECK (("auth"."uid"() = "id"));

CREATE POLICY "Users can read members belonging to the same team" ON "public"."users" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."users_on_team"
WHERE ("users_on_team"."team_id" IN ( SELECT "private"."get_teams_for_authenticated_user"() AS "get_teams_for_authenticated_user")))));

CREATE POLICY "Users can select their own profile." ON "public"."users" FOR SELECT USING (("auth"."uid"() = "id"));

CREATE POLICY "Users can select users if they are in the same team" ON "public"."users" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."users_on_team"
WHERE (("users_on_team"."user_id" = ( SELECT "auth"."uid"() AS "uid")) AND ("users_on_team"."team_id" = "users"."team_id")))));

CREATE POLICY "Users can update own profile." ON "public"."users" FOR UPDATE USING (("auth"."uid"() = "id"));

CREATE POLICY "Users on team can be deleted by a member of the team" ON "public"."users_on_team" FOR DELETE USING (("team_id" IN ( SELECT "private"."get_teams_for_authenticated_user"() AS "get_teams_for_authenticated_user")));
Expand Down Expand Up @@ -1461,10 +1557,18 @@ GRANT ALL ON FUNCTION "public"."calculated_vat"("public"."transactions") TO "ano
GRANT ALL ON FUNCTION "public"."calculated_vat"("public"."transactions") TO "authenticated";
GRANT ALL ON FUNCTION "public"."calculated_vat"("public"."transactions") TO "service_role";

GRANT ALL ON FUNCTION "public"."create_team"("name" character varying) TO "anon";
GRANT ALL ON FUNCTION "public"."create_team"("name" character varying) TO "authenticated";
GRANT ALL ON FUNCTION "public"."create_team"("name" character varying) TO "service_role";

GRANT ALL ON FUNCTION "public"."extract_product_names"("products_json" "json") TO "anon";
GRANT ALL ON FUNCTION "public"."extract_product_names"("products_json" "json") TO "authenticated";
GRANT ALL ON FUNCTION "public"."extract_product_names"("products_json" "json") TO "service_role";

GRANT ALL ON FUNCTION "public"."generate_hmac"("secret_key" "text", "message" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."generate_hmac"("secret_key" "text", "message" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."generate_hmac"("secret_key" "text", "message" "text") TO "service_role";

GRANT ALL ON FUNCTION "public"."generate_id"("size" integer) TO "anon";
GRANT ALL ON FUNCTION "public"."generate_id"("size" integer) TO "authenticated";
GRANT ALL ON FUNCTION "public"."generate_id"("size" integer) TO "service_role";
Expand Down Expand Up @@ -1729,6 +1833,10 @@ GRANT ALL ON FUNCTION "public"."upsert_transaction_enrichment"() TO "anon";
GRANT ALL ON FUNCTION "public"."upsert_transaction_enrichment"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."upsert_transaction_enrichment"() TO "service_role";

GRANT ALL ON FUNCTION "public"."webhook"() TO "anon";
GRANT ALL ON FUNCTION "public"."webhook"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."webhook"() TO "service_role";

GRANT ALL ON FUNCTION "public"."word_similarity"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."word_similarity"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."word_similarity"("text", "text") TO "authenticated";
Expand Down
16 changes: 15 additions & 1 deletion apps/dashboard/.env-example
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
NEXT_PUBLIC_SUPABASE_URL=
# Supabase
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=
NEXT_PUBLIC_SUPABASE_ID=
SUPABASE_SERVICE_KEY=

# Resend
RESEND_API_KEY=

# Loops
LOOPS_ENDPOINT=
LOOPS_API_KEY=

# GoCardLess
GOCARDLESS_SECRET_ID=
GOCARDLESS_SECRET_KEY=

# Upstash
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=

# Novu
NOVU_API_KEY=
NEXT_PUBLIC_TRIGGER_API_KEY=

# Dub
DUB_API_KEY=

# Base64 encoded json (project_id, private_key, client_email)
GOOGLE_APPLICATION_CREDENTIALS=
GOOGLE_APPLICATION_INVOICE_PROCESSOR_ID=
GOOGLE_APPLICATION_EXPENSE_PROCESSOR_ID=

# Teller (Base 64 encoded certificate)
TELLER_CERTIFICATE=
TELLER_CERTIFICATE_PRIVATE_KEY=
Expand Down
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"test": "turbo test --parallel",
"start:dashboard": "turbo start --filter=@midday/dashboard",
"start:website": "turbo start --filter=@midday/website",
"dev:api": "turbo dev --filter=@midday/api",
"dev:dashboard": "turbo dev --filter=@midday/dashboard",
"dev:website": "turbo dev --filter=@midday/website ",
"dev:desktop": "turbo dev --filter=@midday/desktop",
Expand All @@ -24,7 +25,7 @@
"turbo": "2.0.4",
"typescript": "^5.5.2"
},
"packageManager": "[email protected].13",
"packageManager": "[email protected].16",
"resolutions": {
"jackspeak": "2.1.1"
}
Expand Down

0 comments on commit 48676e8

Please sign in to comment.