256 lines
6.6 KiB
TypeScript
256 lines
6.6 KiB
TypeScript
import { createClient, SupabaseClient } from "@supabase/supabase-js";
|
|
import { createBrowserClient } from "@supabase/ssr";
|
|
|
|
export type SupabaseServiceClient = SupabaseClient<Database>;
|
|
|
|
export interface Database {
|
|
public: {
|
|
Tables: {
|
|
email_queue: {
|
|
Row: {
|
|
id: string;
|
|
mail_from: string;
|
|
mail_to: string;
|
|
reply_to: string | null;
|
|
subject: string;
|
|
html: string;
|
|
body_text: string;
|
|
status: string;
|
|
retry_count: number;
|
|
next_retry_at: string;
|
|
error_last: string | null;
|
|
created_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
mail_from: string;
|
|
mail_to: string;
|
|
reply_to?: string | null;
|
|
subject: string;
|
|
html: string;
|
|
body_text: string;
|
|
status?: string;
|
|
retry_count?: number;
|
|
next_retry_at?: string;
|
|
error_last?: string | null;
|
|
created_at?: string;
|
|
};
|
|
Update: {
|
|
status?: string;
|
|
retry_count?: number;
|
|
next_retry_at?: string;
|
|
error_last?: string | null;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
admin_users: {
|
|
Row: {
|
|
id: string;
|
|
email: string;
|
|
name: string | null;
|
|
password_hash: string;
|
|
aktiv: boolean;
|
|
created_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
email: string;
|
|
name?: string | null;
|
|
password_hash: string;
|
|
aktiv?: boolean;
|
|
created_at?: string;
|
|
};
|
|
Update: {
|
|
email?: string;
|
|
name?: string | null;
|
|
password_hash?: string;
|
|
aktiv?: boolean;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
admin_audit_logs: {
|
|
Row: {
|
|
id: string;
|
|
email: string;
|
|
ip_addr: string;
|
|
user_agent: string;
|
|
success: boolean;
|
|
reason: string | null;
|
|
timestamp: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
email: string;
|
|
ip_addr: string;
|
|
user_agent: string;
|
|
success: boolean;
|
|
reason?: string | null;
|
|
timestamp?: string;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
admin_session_blacklist: {
|
|
Row: {
|
|
id: string;
|
|
admin_id: string;
|
|
token_signature: string;
|
|
revoked_at: string;
|
|
reason: string;
|
|
notes: string | null;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
admin_id: string;
|
|
token_signature: string;
|
|
revoked_at?: string;
|
|
reason: string;
|
|
notes?: string | null;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
action_token_blacklist: {
|
|
Row: {
|
|
id: string;
|
|
anfrage_id: string;
|
|
token_signature: string;
|
|
action_type: string;
|
|
used_at: string;
|
|
used_by_ip: string | null;
|
|
notes: string | null;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
anfrage_id: string;
|
|
token_signature: string;
|
|
action_type: string;
|
|
used_at?: string;
|
|
used_by_ip?: string | null;
|
|
notes?: string | null;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
page_views: {
|
|
Row: {
|
|
id: string;
|
|
path: string;
|
|
timestamp: string;
|
|
ip_anon: string | null;
|
|
device_type: string | null;
|
|
browser: string | null;
|
|
os: string | null;
|
|
referrer: string | null;
|
|
session_id: string;
|
|
duration_ms: number | null;
|
|
is_bot: boolean;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
path: string;
|
|
timestamp?: string;
|
|
ip_anon?: string | null;
|
|
device_type?: string | null;
|
|
browser?: string | null;
|
|
os?: string | null;
|
|
referrer?: string | null;
|
|
session_id: string;
|
|
duration_ms?: number | null;
|
|
is_bot?: boolean;
|
|
};
|
|
Update: {
|
|
duration_ms?: number | null;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
phone_clicks: {
|
|
Row: {
|
|
id: number;
|
|
phone_number: string;
|
|
source_page: string;
|
|
source_element: string;
|
|
session_id: string | null;
|
|
ip_anonymized: string | null;
|
|
device_type: string | null;
|
|
browser: string | null;
|
|
os: string | null;
|
|
timestamp: string;
|
|
};
|
|
Insert: {
|
|
phone_number: string;
|
|
source_page: string;
|
|
source_element: string;
|
|
session_id?: string | null;
|
|
ip_anonymized?: string | null;
|
|
device_type?: string | null;
|
|
browser?: string | null;
|
|
os?: string | null;
|
|
timestamp?: string;
|
|
};
|
|
Update: Record<string, never>;
|
|
Relationships: [];
|
|
};
|
|
anfragen: {
|
|
Row: {
|
|
id: string;
|
|
name: string;
|
|
email: string;
|
|
betreff: string;
|
|
nachricht: string | null;
|
|
status: string;
|
|
admin_notizen: string | null;
|
|
kunde_id: string | null;
|
|
created_at: string;
|
|
};
|
|
Insert: {
|
|
id?: string;
|
|
name: string;
|
|
email: string;
|
|
betreff: string;
|
|
nachricht?: string | null;
|
|
status?: string;
|
|
admin_notizen?: string | null;
|
|
kunde_id?: string | null;
|
|
created_at?: string;
|
|
};
|
|
Update: {
|
|
status?: string;
|
|
admin_notizen?: string | null;
|
|
};
|
|
Relationships: [];
|
|
};
|
|
};
|
|
Views: Record<string, never>;
|
|
Functions: Record<string, never>;
|
|
Enums: Record<string, never>;
|
|
CompositeTypes: Record<string, never>;
|
|
};
|
|
}
|
|
|
|
let serviceClient: SupabaseServiceClient | null = null;
|
|
|
|
export function createServiceClient(): SupabaseServiceClient {
|
|
if (serviceClient) return serviceClient;
|
|
|
|
const url = process.env.SUPABASE_URL;
|
|
const key = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
|
|
if (!url || !key) {
|
|
throw new Error("SUPABASE_URL oder SUPABASE_SERVICE_ROLE_KEY fehlt in .env.local");
|
|
}
|
|
|
|
serviceClient = createClient<Database>(url, key, {
|
|
auth: { persistSession: false },
|
|
});
|
|
|
|
return serviceClient;
|
|
}
|
|
|
|
export function createBrowserSupabaseClient() {
|
|
return createBrowserClient<Database>(
|
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
|
);
|
|
}
|