Files
upstream-mirror 93ecc1a6f8
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:48:50 +05:00

188 lines
4.7 KiB
TypeScript

import type {
DatabaseConnection,
Driver,
QueryResult,
} from "https://esm.sh/kysely@0.27.2";
import {
CompiledQuery,
Kysely,
PostgresAdapter,
PostgresIntrospector,
PostgresQueryCompiler,
type Generated,
} from "https://esm.sh/kysely@0.27.2";
export { CompiledQuery };
import type { PoolClient } from "https://deno.land/x/postgres@v0.17.0/mod.ts";
import { Pool } from "https://deno.land/x/postgres@v0.17.0/mod.ts";
// Database schema types
export interface ContactsTable {
id: Generated<number>;
first_name: string | null;
last_name: string | null;
gender: string | null;
title: string | null;
email_jsonb: unknown | null; // JSONB array
phone_jsonb: unknown | null; // JSONB array
background: string | null;
avatar: unknown | null; // JSONB
first_seen: Date | null;
last_seen: Date | null;
has_newsletter: boolean | null;
status: string | null;
tags: number[] | null;
company_id: number | null;
sales_id: number | null;
linkedin_url: string | null;
}
interface TasksTable {
id: Generated<number>;
contact_id: number;
type: string | null;
text: string | null;
due_date: Date;
done_date: Date | null;
sales_id: number | null;
}
interface ContactNotesTable {
id: Generated<number>;
contact_id: number;
text: string | null;
date: Date | null;
sales_id: number | null;
status: string | null;
attachments: unknown[] | null; // JSONB array
}
interface DealsTable {
id: Generated<number>;
name: string;
company_id: number | null;
contact_ids: number[];
category: string | null;
stage: string;
description: string | null;
amount: number | null;
created_at: Date;
updated_at: Date;
archived_at: Date | null;
expected_closing_date: Date | null;
sales_id: number | null;
index: number | null;
}
interface Database {
contacts: ContactsTable;
tasks: TasksTable;
contact_notes: ContactNotesTable;
deals: DealsTable;
}
// Deno Postgres Driver for Kysely
class DenoPostgresDriver implements Driver {
private pool: Pool;
private connections = new WeakMap<PoolClient, DatabaseConnection>();
constructor(pool: Pool) {
this.pool = pool;
}
async init(): Promise<void> {
// Connection pool is already initialized
}
async acquireConnection(): Promise<DatabaseConnection> {
const client = await this.pool.connect();
let connection = this.connections.get(client);
if (!connection) {
connection = new DenoPostgresConnection(client);
this.connections.set(client, connection);
}
return connection;
}
async beginTransaction(connection: DatabaseConnection): Promise<void> {
await connection.executeQuery(CompiledQuery.raw("begin"));
}
async commitTransaction(connection: DatabaseConnection): Promise<void> {
await connection.executeQuery(CompiledQuery.raw("commit"));
}
async rollbackTransaction(connection: DatabaseConnection): Promise<void> {
await connection.executeQuery(CompiledQuery.raw("rollback"));
}
async releaseConnection(connection: DatabaseConnection): Promise<void> {
(connection as DenoPostgresConnection).release();
}
async destroy(): Promise<void> {
await this.pool.end();
}
}
class DenoPostgresConnection implements DatabaseConnection {
private client: PoolClient;
constructor(client: PoolClient) {
this.client = client;
}
async executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>> {
const result = await this.client.queryObject<O>({
text: compiledQuery.sql,
args: compiledQuery.parameters as unknown[],
});
if (
result.command === "INSERT" ||
result.command === "UPDATE" ||
result.command === "DELETE"
) {
return {
numAffectedRows: BigInt(result.rowCount ?? 0),
rows: result.rows ?? [],
};
}
return {
rows: result.rows ?? [],
};
}
streamQuery<O>(
_compiledQuery: CompiledQuery,
_chunkSize?: number,
): AsyncIterableIterator<QueryResult<O>> {
throw new Error("Deno Postgres driver does not support streaming");
}
release() {
this.client.release();
}
}
// Create connection pool
// Use SUPABASE_DB_URL if available (production), otherwise fall back to local dev connection string
const connectionString =
Deno.env.get("SUPABASE_DB_URL") ||
"postgresql://postgres:postgres@db:5432/postgres";
const pool = new Pool(connectionString, 1); // Single connection for edge functions
// Create and export Kysely instance
export const db = new Kysely<Database>({
dialect: {
createAdapter: () => new PostgresAdapter(),
createDriver: () => new DenoPostgresDriver(pool),
createIntrospector: (db: Kysely<any>) => new PostgresIntrospector(db),
createQueryCompiler: () => new PostgresQueryCompiler(),
},
});