fix(db): add missing indexes, bound unbounded queries, parallelize admin queries
- Add 7 missing indexes: User(kycStatus, isActive, createdAt), Listing(createdAt, featuredUntil, expiresAt), Payment(createdAt) - Add take:50 limit to unbounded findMediaByPropertyId and findByPropertyId - Parallelize sequential queries in getUserDetail with Promise.all Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -220,21 +220,22 @@ export class PrismaAdminQueryRepository implements IAdminQueryRepository {
|
|||||||
|
|
||||||
if (!user) return null;
|
if (!user) return null;
|
||||||
|
|
||||||
const transactionsCount = await this.prisma.transaction.count({
|
const [transactionsCount, recentListings] = await Promise.all([
|
||||||
where: { buyerId: userId },
|
this.prisma.transaction.count({
|
||||||
});
|
where: { buyerId: userId },
|
||||||
|
}),
|
||||||
const recentListings = await this.prisma.listing.findMany({
|
this.prisma.listing.findMany({
|
||||||
where: { sellerId: userId },
|
where: { sellerId: userId },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
status: true,
|
status: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
property: { select: { title: true } },
|
property: { select: { title: true } },
|
||||||
},
|
},
|
||||||
orderBy: { createdAt: 'desc' },
|
orderBy: { createdAt: 'desc' },
|
||||||
take: 10,
|
take: 10,
|
||||||
});
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
const recentActivity = recentListings.map((l) => ({
|
const recentActivity = recentListings.map((l) => ({
|
||||||
type: 'listing',
|
type: 'listing',
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export class PrismaValuationRepository implements IValuationRepository {
|
|||||||
const records = await this.prisma.valuation.findMany({
|
const records = await this.prisma.valuation.findMany({
|
||||||
where: { propertyId },
|
where: { propertyId },
|
||||||
orderBy: { createdAt: 'desc' },
|
orderBy: { createdAt: 'desc' },
|
||||||
|
take: 50,
|
||||||
});
|
});
|
||||||
return records.map((r) => this.toDomain(r));
|
return records.map((r) => this.toDomain(r));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export class PrismaPropertyRepository implements IPropertyRepository {
|
|||||||
const mediaList = await this.prisma.propertyMedia.findMany({
|
const mediaList = await this.prisma.propertyMedia.findMany({
|
||||||
where: { propertyId },
|
where: { propertyId },
|
||||||
orderBy: { order: 'asc' },
|
orderBy: { order: 'asc' },
|
||||||
|
take: 50,
|
||||||
});
|
});
|
||||||
return mediaList.map((m) => this.toMediaDomain(m));
|
return mediaList.map((m) => this.toMediaDomain(m));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ model User {
|
|||||||
|
|
||||||
@@index([phone])
|
@@index([phone])
|
||||||
@@index([role])
|
@@index([role])
|
||||||
|
@@index([kycStatus])
|
||||||
|
@@index([isActive])
|
||||||
|
@@index([createdAt])
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OAuthProvider {
|
enum OAuthProvider {
|
||||||
@@ -245,6 +248,9 @@ model Listing {
|
|||||||
@@index([propertyId])
|
@@index([propertyId])
|
||||||
@@index([agentId])
|
@@index([agentId])
|
||||||
@@index([publishedAt])
|
@@index([publishedAt])
|
||||||
|
@@index([createdAt])
|
||||||
|
@@index([featuredUntil])
|
||||||
|
@@index([expiresAt])
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -378,6 +384,7 @@ model Payment {
|
|||||||
@@index([transactionId])
|
@@index([transactionId])
|
||||||
@@index([status])
|
@@index([status])
|
||||||
@@index([providerTxId])
|
@@index([providerTxId])
|
||||||
|
@@index([createdAt])
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user