feat(16-04): enrich dashboard rows with signedCount, totalSigners, hasMultipleSigners
- Import signingTokens and sql from drizzle-orm - Add documents.signers to main select - Fetch token counts per document in single grouped query (avoids N+1) - Build tokenMap for O(1) lookup per row - Produce enrichedRows with signedCount, totalSigners, hasMultipleSigners fields - Pass enrichedRows to DocumentsTable instead of filteredRows
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { auth } from "@/lib/auth";
|
||||
import { db } from "@/lib/db";
|
||||
import { documents, clients } from "@/lib/db/schema";
|
||||
import { eq, desc } from "drizzle-orm";
|
||||
import { documents, clients, signingTokens } from "@/lib/db/schema";
|
||||
import { eq, desc, sql } from "drizzle-orm";
|
||||
import { DocumentsTable } from "../../_components/DocumentsTable";
|
||||
import { DashboardFilters } from "../../_components/DashboardFilters";
|
||||
|
||||
@@ -25,16 +25,44 @@ export default async function DashboardPage({
|
||||
signedAt: documents.signedAt,
|
||||
clientName: clients.name,
|
||||
clientId: documents.clientId,
|
||||
signers: documents.signers,
|
||||
})
|
||||
.from(documents)
|
||||
.leftJoin(clients, eq(documents.clientId, clients.id))
|
||||
.orderBy(desc(documents.createdAt));
|
||||
|
||||
// Fetch signing token counts per document in one query (avoids N+1)
|
||||
const tokenCounts = await db
|
||||
.select({
|
||||
documentId: signingTokens.documentId,
|
||||
total: sql<number>`count(*)`.as("total"),
|
||||
signed: sql<number>`count(${signingTokens.usedAt})`.as("signed"),
|
||||
})
|
||||
.from(signingTokens)
|
||||
.groupBy(signingTokens.documentId);
|
||||
|
||||
const tokenMap = new Map(
|
||||
tokenCounts.map((t) => [
|
||||
t.documentId,
|
||||
{ total: Number(t.total), signed: Number(t.signed) },
|
||||
])
|
||||
);
|
||||
|
||||
const filteredRows =
|
||||
status && (VALID_STATUSES as readonly string[]).includes(status)
|
||||
? allRows.filter((r) => r.status === (status as ValidStatus))
|
||||
: allRows;
|
||||
|
||||
const enrichedRows = filteredRows.map((row) => {
|
||||
const tc = tokenMap.get(row.id);
|
||||
return {
|
||||
...row,
|
||||
signedCount: tc?.signed ?? null,
|
||||
totalSigners: tc?.total ?? null,
|
||||
hasMultipleSigners: Array.isArray(row.signers) && row.signers.length > 0,
|
||||
};
|
||||
});
|
||||
|
||||
const firstName = session?.user?.email?.split("@")[0] ?? "Agent";
|
||||
|
||||
return (
|
||||
@@ -51,7 +79,7 @@ export default async function DashboardPage({
|
||||
<span style={{ fontSize: "0.875rem", color: "#6B7280" }}>Filter by status:</span>
|
||||
<DashboardFilters currentStatus={status} />
|
||||
</div>
|
||||
<DocumentsTable rows={filteredRows} showClientColumn={true} />
|
||||
<DocumentsTable rows={enrichedRows} showClientColumn={true} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user