Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## 2024-05-18 - Concurrent Fetching with Owner IDs in Share Links
**Learning:** In the share system, endpoints processing a share code typically suffer from waterfall latency by first loading target entity details (like a project) and then querying its associated elements (like project lists) using the entity's owner ID (`userId`). However, the `shareLink` object already contains the `userId` field (representing the owner's ID).
**Action:** Always leverage the existing owner's ID within `shareLink` to bypass sequential dependencies and fetch parent entities (like projects) concurrently with their child elements (like user lists) using `Promise.all`.

## 2024-05-23 - Concurrent Parent/Child Data Fetching in API Routes
**Learning:** In backend API routes (e.g. GET requests for entities), sequentially awaiting a parent validation query (like `getProject(userId, projectId)`) and then its child data query (`getProjectLists(userId, projectId)`) creates a database query waterfall that adds unnecessary latency.
**Action:** When the child query does not strictly depend on the result of the parent query (for example, when both rely on existing parameters like `userId` and `projectId`/`listId`), execute both queries concurrently using `Promise.all` and then perform the necessary validation checks (e.g. `if (!project) return 404`).
9 changes: 6 additions & 3 deletions src/app/api/lists/[id]/citations/[citationId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
}

// Verify the list exists and belongs to the user
const list = await getList(userId, listId);
// Fetch list details and citation concurrently by utilizing the userId
const [list, citation] = await Promise.all([
getList(userId, listId),
getCitation(listId, citationId),
]);
Comment on lines 23 to +28

if (!list) {
return NextResponse.json(
{ success: false, error: "List not found" },
{ status: 404 }
);
}

const citation = await getCitation(listId, citationId);

if (!citation) {
return NextResponse.json(
{ success: false, error: "Citation not found" },
Expand Down
9 changes: 6 additions & 3 deletions src/app/api/lists/[id]/citations/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
}

// Verify the list exists and belongs to the user
const list = await getList(userId, listId);
// Fetch list details and list citations concurrently by utilizing the userId
const [list, citations] = await Promise.all([
getList(userId, listId),
getListCitations(listId),
]);
Comment on lines 24 to +29

if (!list) {
return NextResponse.json(
{ success: false, error: "List not found" },
{ status: 404 }
);
}

const citations = await getListCitations(listId);

return NextResponse.json({
success: true,
data: citations,
Expand Down
9 changes: 6 additions & 3 deletions src/app/api/projects/[id]/lists/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
}

// Verify the project exists and belongs to the user
const project = await getProject(userId, projectId);
// Fetch project details and user lists concurrently by utilizing the userId
const [project, lists] = await Promise.all([
getProject(userId, projectId),
getProjectLists(userId, projectId),
]);

if (!project) {
return NextResponse.json(
{ success: false, error: "Project not found" },
{ status: 404 }
);
}

const lists = await getProjectLists(userId, projectId);

return NextResponse.json({
success: true,
data: lists,
Expand Down
Loading