From 7387b91c434c6529f4aa0d3256e15ba1b3f816dd Mon Sep 17 00:00:00 2001 From: John Moorman <45500240+mojoro@users.noreply.github.com> Date: Wed, 25 Mar 2026 22:56:23 +0100 Subject: [PATCH 01/48] Select only needed jobPool columns on dashboard to cut payload 80-90% --- src/app/(dashboard)/actions-sync.ts | 10 +++++-- src/app/(dashboard)/dashboard/actions.ts | 3 +- .../jobs/[id]/_components/JobDetailClient.tsx | 16 ++++++---- src/app/(dashboard)/jobs/[id]/page.tsx | 3 +- src/lib/store.ts | 5 +--- src/types/index.ts | 30 ++++++++++++++++--- 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/app/(dashboard)/actions-sync.ts b/src/app/(dashboard)/actions-sync.ts index 638205c..f9f6cf8 100644 --- a/src/app/(dashboard)/actions-sync.ts +++ b/src/app/(dashboard)/actions-sync.ts @@ -4,6 +4,7 @@ import { auth } from "@clerk/nextjs/server"; import { prisma } from "@/lib/prisma"; import { getActiveProfile } from "@/lib/get-active-profile"; import { getFollowUpCount } from "@/app/(dashboard)/pipeline/actions"; +import { jobPoolSummarySelect } from "@/types"; /** * Fetches all dashboard data for the authenticated user. @@ -38,12 +39,17 @@ export async function fetchDashboardData() { }), prisma.job.findMany({ where: { profileId: activeProfile.id }, - include: { jobPool: true, application: { select: { status: true } } }, + include: { + jobPool: { select: jobPoolSummarySelect }, + application: { select: { status: true } }, + }, orderBy: { createdAt: "desc" }, }), prisma.application.findMany({ where: { profileId: activeProfile.id }, - include: { job: { include: { jobPool: true } } }, + include: { + job: { include: { jobPool: { select: jobPoolSummarySelect } } }, + }, orderBy: { updatedAt: "desc" }, }), getFollowUpCount(userId), diff --git a/src/app/(dashboard)/dashboard/actions.ts b/src/app/(dashboard)/dashboard/actions.ts index 10438c7..9dfb944 100644 --- a/src/app/(dashboard)/dashboard/actions.ts +++ b/src/app/(dashboard)/dashboard/actions.ts @@ -13,6 +13,7 @@ import { buildAnalysisSystemPrompt, parseAiAnalysisResponse } from "@/lib/ai-ana import { checkRateLimit } from "@/lib/rate-limit"; import { updateCustomJobSchema } from "@/lib/validations"; import type { SortOption } from "@/lib/jobs"; +import { jobPoolSummarySelect } from "@/types"; import type { JobWithApplication } from "@/types"; export async function getMoreJobs( @@ -34,7 +35,7 @@ export async function getMoreJobs( const jobs = await prisma.job.findMany({ where: buildWhereClause(profileId, filter), - include: { jobPool: true, application: { select: { status: true } } }, + include: { jobPool: { select: jobPoolSummarySelect }, application: { select: { status: true } } }, orderBy: buildOrderBy(safeSort), take: 25, cursor: { id: cursor }, diff --git a/src/app/(dashboard)/jobs/[id]/_components/JobDetailClient.tsx b/src/app/(dashboard)/jobs/[id]/_components/JobDetailClient.tsx index 847929b..5f95264 100644 --- a/src/app/(dashboard)/jobs/[id]/_components/JobDetailClient.tsx +++ b/src/app/(dashboard)/jobs/[id]/_components/JobDetailClient.tsx @@ -37,9 +37,10 @@ const JOB_TYPE_LABELS: Record = { interface JobDetailClientProps { jobId: string; + description: string | null; } -export function JobDetailClient({ jobId }: JobDetailClientProps) { +export function JobDetailClient({ jobId, description }: JobDetailClientProps) { const hydrated = useDashboardStore((s) => s.hydrated); const job = useDashboardStore((s) => s.jobs.find((j) => j.id === jobId) ?? null); const [editing, setEditing] = useState(false); @@ -166,6 +167,7 @@ export function JobDetailClient({ jobId }: JobDetailClientProps) { {editing && isCustom && ( { setSaving(true); setSaveError(null); @@ -194,7 +196,7 @@ export function JobDetailClient({ jobId }: JobDetailClientProps) { className="rounded-xl border border-[var(--border)] bg-[var(--bg-card)] p-6" style={{ boxShadow: "var(--shadow-card)" }} > - + @@ -336,11 +338,13 @@ type JobForEdit = NonNullable["job function CustomJobEditForm({ job, + description, onSave, saving, saveError, }: { job: JobForEdit; + description: string; onSave: (data: unknown) => void; saving: boolean; saveError: string | null; @@ -356,7 +360,7 @@ function CustomJobEditForm({ const [salaryMax, setSalaryMax] = useState(pool.salaryMax?.toString() ?? ""); const [currency, setCurrency] = useState(pool.currency ?? ""); const [skills, setSkills] = useState(pool.skills.join(", ")); - const [description, setDescription] = useState(pool.description); + const [editDescription, setEditDescription] = useState(description ?? ""); function handleSubmit(e: React.FormEvent) { e.preventDefault(); @@ -365,7 +369,7 @@ function CustomJobEditForm({ profileId: job.profileId, title: title.trim(), company: company.trim(), - description: description.trim(), + description: editDescription.trim(), location: location.trim() || null, locationType: locationType || null, url: url.trim() || null, @@ -447,8 +451,8 @@ function CustomJobEditForm({