From e68b9b5cea685405411fe943e0e2226ee526747b Mon Sep 17 00:00:00 2001 From: Okeke Chinedu Emmanuel Date: Tue, 30 Jun 2026 05:23:05 +0100 Subject: [PATCH 1/3] Add stream token address index --- .../20260630000000_add_stream_token_address_index/migration.sql | 2 ++ backend/prisma/schema.prisma | 1 + 2 files changed, 3 insertions(+) create mode 100644 backend/prisma/migrations/20260630000000_add_stream_token_address_index/migration.sql diff --git a/backend/prisma/migrations/20260630000000_add_stream_token_address_index/migration.sql b/backend/prisma/migrations/20260630000000_add_stream_token_address_index/migration.sql new file mode 100644 index 00000000..54ce5daf --- /dev/null +++ b/backend/prisma/migrations/20260630000000_add_stream_token_address_index/migration.sql @@ -0,0 +1,2 @@ +-- CreateIndex +CREATE INDEX IF NOT EXISTS "Stream_tokenAddress_idx" ON "Stream"("tokenAddress"); diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index bfece5c2..ce3f39be 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -51,6 +51,7 @@ model Stream { @@index([sender]) @@index([recipient]) + @@index([tokenAddress]) @@index([streamId]) @@index([isActive]) @@index([isPaused]) From 1e13610eff74070db20ac8d94e22a3528f741a16 Mon Sep 17 00:00:00 2001 From: Okeke Chinedu Emmanuel Date: Tue, 30 Jun 2026 05:30:12 +0100 Subject: [PATCH 2/3] Fix Soroban worker Prisma type import --- backend/src/workers/soroban-event-worker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/workers/soroban-event-worker.ts b/backend/src/workers/soroban-event-worker.ts index e4e65f83..6c9b9aa4 100644 --- a/backend/src/workers/soroban-event-worker.ts +++ b/backend/src/workers/soroban-event-worker.ts @@ -1,5 +1,6 @@ import { rpc, xdr, StrKey } from '@stellar/stellar-sdk'; -import { prisma, Prisma } from '../lib/prisma.js'; +import { prisma } from '../lib/prisma.js'; +import type { Prisma } from '../generated/prisma/index.js'; import { INDEXER_STATE_ID } from '../lib/indexer-state.js'; import { sseService } from '../services/sse.service.js'; import logger from '../logger.js'; From 320e7f68e09638330f4720d98efa7f377b6d9a91 Mon Sep 17 00:00:00 2001 From: Okeke Chinedu Emmanuel Date: Tue, 30 Jun 2026 05:46:10 +0100 Subject: [PATCH 3/3] Configure Postgres pool limits --- backend/.env.example | 10 ++++++++++ backend/prisma/seed.ts | 5 ++--- backend/src/lib/pg-pool.ts | 21 +++++++++++++++++++++ backend/src/lib/prisma.ts | 5 ++--- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 backend/src/lib/pg-pool.ts diff --git a/backend/.env.example b/backend/.env.example index f754bc8d..5035a28b 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,6 +1,16 @@ # Database DATABASE_URL="postgresql://user:password@localhost:5433/flowfi?schema=public" +# PostgreSQL pool settings +# Maximum database connections per backend process (default: 10) +PG_POOL_MAX=10 +# How long an idle connection stays open before being closed (milliseconds, default: 30000) +PG_IDLE_TIMEOUT_MS=30000 +# How long to wait when establishing a new database connection (milliseconds, default: 5000) +PG_CONNECTION_TIMEOUT_MS=5000 +# Maximum time a PostgreSQL statement may run before cancellation (milliseconds, default: 30000) +PG_STATEMENT_TIMEOUT_MS=30000 + # Server PORT=3001 NODE_ENV=development diff --git a/backend/prisma/seed.ts b/backend/prisma/seed.ts index d7ebc71c..ccf856aa 100644 --- a/backend/prisma/seed.ts +++ b/backend/prisma/seed.ts @@ -1,9 +1,8 @@ -import pg from 'pg'; import { PrismaPg } from '@prisma/adapter-pg'; import { PrismaClient } from '../src/generated/prisma/index.js'; +import { createPgPool } from '../src/lib/pg-pool.js'; -const connectionString = process.env.DATABASE_URL; -const pool = new pg.Pool({ connectionString }); +const pool = createPgPool(); const adapter = new PrismaPg(pool); const prisma = new PrismaClient({ adapter }); diff --git a/backend/src/lib/pg-pool.ts b/backend/src/lib/pg-pool.ts new file mode 100644 index 00000000..fcb098f2 --- /dev/null +++ b/backend/src/lib/pg-pool.ts @@ -0,0 +1,21 @@ +import pg from 'pg'; + +const parsePositiveIntegerEnv = (name: string, defaultValue: number): number => { + const rawValue = process.env[name]; + + if (!rawValue) return defaultValue; + + const parsedValue = Number.parseInt(rawValue, 10); + + return Number.isInteger(parsedValue) && parsedValue > 0 ? parsedValue : defaultValue; +}; + +export const createPgPoolConfig = (): pg.PoolConfig => ({ + connectionString: process.env.DATABASE_URL, + max: parsePositiveIntegerEnv('PG_POOL_MAX', 10), + idleTimeoutMillis: parsePositiveIntegerEnv('PG_IDLE_TIMEOUT_MS', 30_000), + connectionTimeoutMillis: parsePositiveIntegerEnv('PG_CONNECTION_TIMEOUT_MS', 5_000), + statement_timeout: parsePositiveIntegerEnv('PG_STATEMENT_TIMEOUT_MS', 30_000), +}); + +export const createPgPool = () => new pg.Pool(createPgPoolConfig()); diff --git a/backend/src/lib/prisma.ts b/backend/src/lib/prisma.ts index 0ea5168a..fd4ddfe2 100644 --- a/backend/src/lib/prisma.ts +++ b/backend/src/lib/prisma.ts @@ -1,16 +1,15 @@ import pg from 'pg'; import { PrismaPg } from '@prisma/adapter-pg'; import { PrismaClient } from '../generated/prisma/index.js'; +import { createPgPool } from './pg-pool.js'; const globalForPrisma = global as unknown as { prisma?: PrismaClient; pool?: pg.Pool; }; -const connectionString = process.env.DATABASE_URL; - if (!globalForPrisma.pool) { - globalForPrisma.pool = new pg.Pool({ connectionString }); + globalForPrisma.pool = createPgPool(); } const adapter = new PrismaPg(globalForPrisma.pool);