OUT-3545: parallelize home render and batch Copilot price fetch#240
OUT-3545: parallelize home render and batch Copilot price fetch#240SandipBajracharya merged 3 commits intomasterfrom
Conversation
Initial dashboard load was dominated by two waterfalls. (1) Home.tsx awaited token validation, portal connection, sync status, latest sync log (via HTTP self-call) and workspace info strictly in sequence. (2) ProductService.getFlattenProductList fetched prices per-product through a global Bottleneck (4 concurrent / 200ms), so N products meant N throttled round-trips before SettingAccordion could mount. Server render now runs checkPortalConnection, getWorkspaceInfo and SyncLogService.getLatestSyncSuccessLog in parallel after token validation; syncFlag/isEnabled are read from the eager-loaded portalConnection.setting relation instead of a second DB round-trip; the HTTP self-call to /api/quickbooks/syncLog/success is replaced by a direct service call. Add (home)/loading.tsx for segment-level streaming and share it from Main.tsx's client-side loading state. Workspace-wide listPrices (paginated) replaces the per-product loop in getFlattenProductList, dropping calls from 1+N to ~1+ceil(prices/page) and removing the bottleneck dependency on this read path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile Summary
Confidence Score: 4/5Safe to merge; the one open finding is a minor inefficiency with no correctness impact. The prior P1 (uncaught sync-log DB error crashing the page) is fixed with src/app/(home)/Home.tsx — unnecessary unconditional sync-log DB query; src/app/api/quickbooks/product/product.service.ts — acknowledged full-price-sweep trade-off documented in code comments. Important Files Changed
Sequence DiagramsequenceDiagram
participant Browser
participant Home as Home.tsx (Server)
participant DB as DB / token.service
participant SyncLog as SyncLogService
participant Copilot as CopilotAPI
Browser->>Home: GET / (token, type)
Home->>Home: getTokenPayload(token)
par Parallel fetches
Home->>DB: checkPortalConnection(workspaceId)
Home->>DB: getWorkspaceInfo(token)
Home->>SyncLog: getLatestSyncSuccessLog() [.catch → null]
end
DB-->>Home: portalConnection (with setting)
DB-->>Home: workspace
SyncLog-->>Home: latestSuccessLog | null
alt portalConnectionStatus && !syncFlag
Home->>Home: reconnectIfCta(type)
end
Home-->>Browser: AppProvider stream
note over Browser,Copilot: Product flatten endpoint (separate request)
Browser->>Copilot: GET /api/quickbooks/product/flatten
par Parallel
Copilot->>Copilot: getProducts(limit=1000)
loop paginate all prices
Copilot->>Copilot: getPrices(limit=1000, nextToken?)
end
end
Copilot-->>Browser: { products: flattened[] }
Reviews (2): Last reviewed commit: "fix(OUT-3545): preserve home render on s..." | Re-trigger Greptile |
…oduct pagination knobs Home.tsx: catch errors from getLatestSyncSuccessLog inside Promise.all so a transient DB failure nulls the timestamp instead of crashing the render (matches the prior HTTP path's withErrorHandler swallowing). Product flatten endpoint: remove the limit/nextToken query params (only consumer is the SWR hook, which never passed them and the response DTO never exposed nextToken). Service now hardcodes MAX_PRODUCT_LIST_LIMIT for the single-page workload it actually serves, and the workspace-wide price walk is documented. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@greptileai review |
priosshrsth
left a comment
There was a problem hiding this comment.
One minor optional suggestion. But the PR looks good to me and good one. This should help a lot. You are free to merge it as it is if you want.
Summary
src/app/(home)/Home.tsx); replace internal API round-trip with directSyncLogServicecall.ProductService.getFlattenProductList— paginate/pricesonce and group byproductIdinstead of N+1 calls per product (dropsbottleneck).loading.tsxfor the home segment and reuse it fromdashboard/Main; drop the now-unusedcheckSyncStatusaction (sync flag now read from the eagerly-loaded portal connection's setting).Test plan
reconnectflow still triggers when?type=...is passed.getFlattenProductListand confirm products with multiple prices still render every price row, sorted ascending by amount.nextToken).yarn lint:check && yarn testclean.🤖 Generated with Claude Code