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
16 changes: 9 additions & 7 deletions src/routes/(console)/organization-[organization]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,13 @@
});

const projectsToArchive = $derived.by(() => {
return isCloud
? data.projects.projects.filter((project) => project.status === 'archived')
: [];
return isCloud && data.archivedProjectsPage ? data.archivedProjectsPage : [];
});

const activeProjects = $derived(data.projects.projects);

const activeProjectsCount = $derived(data.projects.total);

function filterPlatforms(platforms: { name: string; icon: string }[]) {
return platforms.filter(
(value, index, self) => index === self.findIndex((t) => t.name === value.name)
Expand Down Expand Up @@ -235,13 +237,13 @@
</Alert.Inline>
{/if}

{#if data.projects.total > 0}
{#if activeProjectsCount > 0}
<CardContainer
disableEmpty={!$canWriteProjects}
total={data.projects.total}
total={activeProjectsCount}
offset={data.offset}
on:click={handleCreateProject}>
{#each data.projects.projects as project}
{#each activeProjects as project}
{@const platforms = filterPlatforms(
project.platforms.map((platform) => getPlatformInfo(platform.type))
)}
Expand Down Expand Up @@ -323,7 +325,7 @@
name="Projects"
limit={data.limit}
offset={data.offset}
total={data.projects.total} />
total={activeProjectsCount} />

<!-- Archived Projects Section -->
<ArchiveProject
Expand Down
100 changes: 79 additions & 21 deletions src/routes/(console)/organization-[organization]/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,84 @@ export const load: PageLoad = async ({ params, url, route, depends, parent }) =>
const offset = pageToOffset(page, limit);
const search = getSearch(url);

const projects = await sdk.forConsole.projects.list({
queries: [
Query.offset(offset),
Query.equal('teamId', params.organization),
Query.limit(limit),
Query.orderDesc(''),
Query.select(['$id', 'name', 'platforms', 'region', ...(isCloud ? ['status'] : [])])
],
search: search || undefined
});

// set `default` if no region!
for (const project of projects.projects) {
project.region ??= 'default';
}
if (isCloud) {
const [activeProjects, archivedProjects, activeTotal, archivedTotal] = await Promise.all([
sdk.forConsole.projects.list({
queries: [
Query.offset(offset),
Query.equal('teamId', params.organization),
Query.or([Query.equal('status', 'active'), Query.isNull('status')]),
Query.limit(limit),
Query.orderDesc('')
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.equal('status', 'archived'),
Query.limit(1000)
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.or([Query.equal('status', 'active'), Query.isNull('status')])
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.equal('status', 'archived')
],
search: search || undefined
})
]);
Comment on lines +24 to +57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Hardcoded limit will silently truncate archived projects.

Line 39 hardcodes Query.limit(1000) for archived projects. If an organization has more than 1000 archived projects, they will be silently truncated without any indication to the user.

Additionally, the activeTotal and archivedTotal queries (lines 43-56) fetch all matching projects without pagination just to obtain counts, which could be expensive for organizations with many projects.

Finally, Line 31 uses Query.orderDesc('') with an empty string parameter, which appears incorrect. This should either specify a field name (e.g., '$createdAt') or be removed entirely.

🔎 Proposed fixes

Fix 1: Remove hardcoded limit and use pagination for archived projects

If the UI needs all archived projects, consider removing the limit or using a much higher value with proper pagination:

         sdk.forConsole.projects.list({
             queries: [
                 Query.equal('teamId', params.organization),
                 Query.equal('status', 'archived'),
-                Query.limit(1000)
+                Query.limit(5000)  // Or implement pagination for archived projects
             ],
             search: search || undefined
         }),

Fix 2: Use count-only queries for totals

If the SDK supports count queries, use them instead of fetching all records:

-        sdk.forConsole.projects.list({
+        sdk.forConsole.projects.count({
             queries: [
                 Query.equal('teamId', params.organization),
                 Query.or([Query.equal('status', 'active'), Query.isNull('status')])
             ],
             search: search || undefined
         }),
-        sdk.forConsole.projects.list({
+        sdk.forConsole.projects.count({
             queries: [
                 Query.equal('teamId', params.organization),
                 Query.equal('status', 'archived')
             ],
             search: search || undefined
         })

Fix 3: Correct or remove the empty orderDesc parameter

                 Query.limit(limit),
-                Query.orderDesc('')
+                Query.orderDesc('$createdAt')
             ],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [activeProjects, archivedProjects, activeTotal, archivedTotal] = await Promise.all([
sdk.forConsole.projects.list({
queries: [
Query.offset(offset),
Query.equal('teamId', params.organization),
Query.or([Query.equal('status', 'active'), Query.isNull('status')]),
Query.limit(limit),
Query.orderDesc('')
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.equal('status', 'archived'),
Query.limit(1000)
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.or([Query.equal('status', 'active'), Query.isNull('status')])
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.equal('status', 'archived')
],
search: search || undefined
})
]);
const [activeProjects, archivedProjects, activeTotal, archivedTotal] = await Promise.all([
sdk.forConsole.projects.list({
queries: [
Query.offset(offset),
Query.equal('teamId', params.organization),
Query.or([Query.equal('status', 'active'), Query.isNull('status')]),
Query.limit(limit),
Query.orderDesc('$createdAt')
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.equal('status', 'archived'),
Query.limit(5000)
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.or([Query.equal('status', 'active'), Query.isNull('status')])
],
search: search || undefined
}),
sdk.forConsole.projects.list({
queries: [
Query.equal('teamId', params.organization),
Query.equal('status', 'archived')
],
search: search || undefined
})
]);
🤖 Prompt for AI Agents
In src/routes/(console)/organization-[organization]/+page.ts around lines 24 to
57: the archived projects list uses a hardcoded Query.limit(1000) which can
silently truncate results, the activeTotal/archivedTotal requests fetch full
records to compute counts (expensive) and Query.orderDesc('') is invalid.
Replace the hardcoded limit by implementing proper pagination for archived
projects (accept page/limit params and request only that page) or remove the
limit if the UI truly needs all results and handle streaming/paging; change the
total queries to use the SDK's count-only endpoint/query (or a
Query.count()/meta flag) instead of listing all records; and fix
Query.orderDesc('') by supplying a valid field name (e.g. '$createdAt') or
remove the orderDesc call entirely.


for (const project of activeProjects.projects) {
project.region ??= 'default';
}
for (const project of archivedProjects.projects) {
project.region ??= 'default';
}

return {
offset,
limit,
projects: {
...activeProjects,
projects: activeProjects.projects,
total: activeTotal.total
},
activeProjectsPage: activeProjects.projects,
archivedProjectsPage: archivedProjects.projects,
activeTotalOverall: activeTotal.total,
archivedTotalOverall: archivedTotal.total,
search
};
} else {
const projects = await sdk.forConsole.projects.list({
queries: [
Query.offset(offset),
Query.equal('teamId', params.organization),
Query.limit(limit),
Query.orderDesc('')
],
search: search || undefined
});

return {
offset,
limit,
projects,
search
};
// set `default` if no region!
for (const project of projects.projects) {
project.region ??= 'default';
}

return {
offset,
limit,
projects,
search
};
}
};