From f2372e1aa6288168e1b487d753c510828c3c57b7 Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaury1729@users.noreply.github.com> Date: Mon, 18 Dec 2023 20:36:57 +0100 Subject: [PATCH 1/2] Update bulk table --- src/app/api/v1/bulk/webhook/route.ts | 12 ++---------- src/pages/bulk.tsx | 9 +++------ src/supabase/database.types.ts | 21 ++++++++++----------- supabase/migrations/20231212135226_bulk.sql | 3 ++- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/app/api/v1/bulk/webhook/route.ts b/src/app/api/v1/bulk/webhook/route.ts index c90a4812..e94ac9f5 100644 --- a/src/app/api/v1/bulk/webhook/route.ts +++ b/src/app/api/v1/bulk/webhook/route.ts @@ -5,7 +5,7 @@ import { removeSensitiveData } from "@/util/api"; import { Tables } from "@/supabase/database.types"; export interface WebhookExtra { - bulkEmailId: string; + bulkEmailId: number; userId: string; endpoint: string; } @@ -38,20 +38,12 @@ export const POST = async (req: NextRequest): Promise => { is_reachable: output.is_reachable, verif_method: output.debug?.smtp?.verif_method?.type, result: removeSensitiveData(output), + bulk_email_id: extra.bulkEmailId, }) .select("*"); if (res1.error) { return Response.json(res1.error, res1); } - // Update bulk_emails table - const res2 = await supabaseAdmin - .from("bulk_emails") - .update({ call_id: res1.data[0].id }) - .eq("id", extra.bulkEmailId); - if (res2.error) { - return Response.json(res2.error, res2); - } - return Response.json({ message: "ok" }, { status: 200 }); }; diff --git a/src/pages/bulk.tsx b/src/pages/bulk.tsx index 0160ba67..64f4affd 100644 --- a/src/pages/bulk.tsx +++ b/src/pages/bulk.tsx @@ -1,4 +1,4 @@ -import { Button, Page, Spacer, Table, Text, Textarea } from "@geist-ui/react"; +import { Button, Page, Spacer, Text, Textarea } from "@geist-ui/react"; import { CheckEmailOutput } from "@reacherhq/api/lib"; import React, { useEffect, useState } from "react"; @@ -46,7 +46,8 @@ export default function Bulk({ onVerified }: BulkProps): React.ReactElement { console.log("FETCHING BULK JOBS..."); const res = await supabase .from("bulk_jobs") - .select(`*,bulk_emails(*)`); + .select(`*,bulk_emails(*)`) + .order("created_at", { ascending: false }); if (res.error) { sentryException(res.error); return; @@ -121,10 +122,6 @@ export default function Bulk({ onVerified }: BulkProps): React.ReactElement { - - -
-
ALLJOBS: {bulkJobs.map((job) => ( diff --git a/src/supabase/database.types.ts b/src/supabase/database.types.ts index 2ecf5e8b..fc7117a4 100644 --- a/src/supabase/database.types.ts +++ b/src/supabase/database.types.ts @@ -12,21 +12,18 @@ export interface Database { bulk_emails: { Row: { bulk_job_id: number; - call_id: number | null; created_at: string | null; email: string; id: number; }; Insert: { bulk_job_id: number; - call_id?: number | null; created_at?: string | null; email: string; id?: number; }; Update: { bulk_job_id?: number; - call_id?: number | null; created_at?: string | null; email?: string; id?: number; @@ -38,13 +35,6 @@ export interface Database { isOneToOne: false; referencedRelation: "bulk_jobs"; referencedColumns: ["id"]; - }, - { - foreignKeyName: "bulk_emails_call_id_fkey"; - columns: ["call_id"]; - isOneToOne: false; - referencedRelation: "calls"; - referencedColumns: ["id"]; } ]; }; @@ -81,6 +71,7 @@ export interface Database { Row: { backend: string | null; backend_ip: string | null; + bulk_email_id: number | null; created_at: string | null; domain: string | null; duration: number | null; @@ -97,6 +88,7 @@ export interface Database { Insert: { backend?: string | null; backend_ip?: string | null; + bulk_email_id?: number | null; created_at?: string | null; domain?: string | null; duration?: number | null; @@ -113,6 +105,7 @@ export interface Database { Update: { backend?: string | null; backend_ip?: string | null; + bulk_email_id?: number | null; created_at?: string | null; domain?: string | null; duration?: number | null; @@ -127,6 +120,13 @@ export interface Database { verification_id?: string; }; Relationships: [ + { + foreignKeyName: "calls_bulk_email_id_fkey"; + columns: ["bulk_email_id"]; + isOneToOne: false; + referencedRelation: "bulk_emails"; + referencedColumns: ["id"]; + }, { foreignKeyName: "calls_user_id_fkey"; columns: ["user_id"]; @@ -366,7 +366,6 @@ export interface Database { Views: { sub_and_calls: { Row: { - api_token: string | null; current_period_end: string | null; current_period_start: string | null; number_of_calls: number | null; diff --git a/supabase/migrations/20231212135226_bulk.sql b/supabase/migrations/20231212135226_bulk.sql index 232fed4d..d773b2b8 100644 --- a/supabase/migrations/20231212135226_bulk.sql +++ b/supabase/migrations/20231212135226_bulk.sql @@ -14,7 +14,6 @@ CREATE POLICY "Can only view own bulk jobs." CREATE TABLE bulk_emails ( id SERIAL NOT NULL PRIMARY KEY, bulk_job_id INTEGER NOT NULL REFERENCES bulk_jobs (id), - call_id INTEGER REFERENCES calls (id), email TEXT NOT NULL, created_at timestamp with time zone DEFAULT timezone('utc'::text, now()) ); @@ -32,3 +31,5 @@ CREATE POLICY "Can only view own bulk emails." AND auth.uid() = bulk_jobs.user_id ) ); + +ALTER TABLE calls ADD COLUMN bulk_email_id INTEGER REFERENCES bulk_emails (id); \ No newline at end of file From f1c287662edf65cf30a615fc1c27b07f7193fc0c Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaury1729@users.noreply.github.com> Date: Mon, 18 Dec 2023 22:02:01 +0100 Subject: [PATCH 2/2] Update UI --- src/pages/bulk.tsx | 36 +++++++------------ src/supabase/database.types.ts | 36 ++++++++++++++++++- .../20231218194337_bulk_jobs_info.sql | 18 ++++++++++ 3 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 supabase/migrations/20231218194337_bulk_jobs_info.sql diff --git a/src/pages/bulk.tsx b/src/pages/bulk.tsx index 64f4affd..117053ed 100644 --- a/src/pages/bulk.tsx +++ b/src/pages/bulk.tsx @@ -1,4 +1,4 @@ -import { Button, Page, Spacer, Text, Textarea } from "@geist-ui/react"; +import { Button, Page, Spacer, Table, Text, Textarea } from "@geist-ui/react"; import { CheckEmailOutput } from "@reacherhq/api/lib"; import React, { useEffect, useState } from "react"; @@ -22,16 +22,12 @@ interface BulkProps { onVerified?(result: CheckEmailOutput): Promise; } -interface BulkJobWithEmails extends Tables<"bulk_jobs"> { - bulk_emails: Tables<"bulk_emails">[]; -} - export default function Bulk({ onVerified }: BulkProps): React.ReactElement { const { user, userDetails } = useUser(); const [emails, setEmails] = useState(""); const [loading, setLoading] = useState(false); - const [bulkJobs, setBulkJobs] = useState([]); + const [bulkJobs, setBulkJobs] = useState[]>([]); useEffect(() => { // This is a temporary redirect to the dashboard while I still work @@ -45,9 +41,8 @@ export default function Bulk({ onVerified }: BulkProps): React.ReactElement { setInterval(async () => { console.log("FETCHING BULK JOBS..."); const res = await supabase - .from("bulk_jobs") - .select(`*,bulk_emails(*)`) - .order("created_at", { ascending: false }); + .from>("bulk_jobs_info") + .select("*"); if (res.error) { sentryException(res.error); return; @@ -122,20 +117,15 @@ export default function Bulk({ onVerified }: BulkProps): React.ReactElement { -
- ALLJOBS: - {bulkJobs.map((job) => ( -
- {job.id} -{" "} - { - job.bulk_emails.filter( - ({ call_id }) => !!call_id - ).length - } - /{job.bulk_emails.length} -
- ))} -
+ + + + + +
); diff --git a/src/supabase/database.types.ts b/src/supabase/database.types.ts index fc7117a4..29326eae 100644 --- a/src/supabase/database.types.ts +++ b/src/supabase/database.types.ts @@ -35,6 +35,13 @@ export interface Database { isOneToOne: false; referencedRelation: "bulk_jobs"; referencedColumns: ["id"]; + }, + { + foreignKeyName: "bulk_emails_bulk_job_id_fkey"; + columns: ["bulk_job_id"]; + isOneToOne: false; + referencedRelation: "bulk_jobs_info"; + referencedColumns: ["job_id"]; } ]; }; @@ -364,6 +371,24 @@ export interface Database { }; }; Views: { + bulk_jobs_info: { + Row: { + created_at: string | null; + job_id: number | null; + number_of_emails: number | null; + user_id: string | null; + verified: number | null; + }; + Relationships: [ + { + foreignKeyName: "bulk_jobs_user_id_fkey"; + columns: ["user_id"]; + isOneToOne: false; + referencedRelation: "users"; + referencedColumns: ["id"]; + } + ]; + }; sub_and_calls: { Row: { current_period_end: string | null; @@ -385,7 +410,16 @@ export interface Database { }; }; Functions: { - [_ in never]: never; + bulk_job_info: { + Args: { + job_id: number; + }; + Returns: { + number_of_email: number; + verified: number; + created_at: string; + }[]; + }; }; Enums: { is_reachable_type: "safe" | "invalid" | "risky" | "unknown"; diff --git a/supabase/migrations/20231218194337_bulk_jobs_info.sql b/supabase/migrations/20231218194337_bulk_jobs_info.sql new file mode 100644 index 00000000..9d073e60 --- /dev/null +++ b/supabase/migrations/20231218194337_bulk_jobs_info.sql @@ -0,0 +1,18 @@ +CREATE VIEW bulk_jobs_info AS + SELECT + bj.id AS job_id, + bj.user_id, + bj.created_at, + COUNT(DISTINCT be.id) AS number_of_emails, + COUNT(DISTINCT CASE WHEN c.id IS NOT NULL THEN be.id ELSE NULL END) AS verified + FROM + bulk_jobs bj + LEFT JOIN + bulk_emails be ON bj.id = be.bulk_job_id + LEFT JOIN + calls c ON be.id = c.bulk_email_id + GROUP BY + bj.id + ORDER BY + bj.created_at DESC; +