feat(stls): flat package list, drop heuristic auto-grouping

Render the STL view as a flat per-package list (listDisplayItems no longer
collapses packages into group rows) and hide the Ungrouped tab, now that the
creator filter organizes the list. Remove the worker's heuristic auto-grouping
passes (rule/time/pattern/creator/zip-path/reply-chain/caption); album grouping
is kept. Existing groups and manual grouping actions are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-23 11:05:18 +02:00
co-authored by Claude Opus 4.8
parent 2252ac01f5
commit 21bd46010f
3 changed files with 23 additions and 49 deletions
+3 -8
View File
@@ -500,14 +500,9 @@ export function StlTable({
</Badge>
)}
</TabsTrigger>
<TabsTrigger value="ungrouped" className="gap-1.5">
Ungrouped
{ungroupedTotalCount > 0 && (
<Badge variant="secondary" className="h-5 px-1.5 text-[10px]">
{ungroupedTotalCount}
</Badge>
)}
</TabsTrigger>
{/* "Ungrouped" tab hidden: the STL list is now flat and grouping is
no longer surfaced here. The tab content below is kept (unreachable)
to avoid churn; remove it and its data fetch if grouping is dropped. */}
</TabsList>
<TabsContent value="packages" className="space-y-4">
+12 -12
View File
@@ -135,31 +135,31 @@ export async function listDisplayItems(options: {
const sortCol = sortBy === "fileName" ? `"fileName"` : sortBy === "fileSize" ? `"fileSize"` : `"indexedAt"`;
const sortDir = order === "asc" ? "ASC" : "DESC";
// Step 1: Count display items
// NOTE: The STL list is intentionally FLAT — every package is its own display
// row regardless of packageGroupId. Grouping is no longer surfaced in this
// view (the creator column/filter organizes the list instead). PackageGroup
// rows and the manual grouping actions still exist in the DB/UI; they just
// don't drive this list's layout anymore.
// Step 1: Count display items (one per package)
const countResult = await prisma.$queryRawUnsafe<[{ count: bigint }]>(
`SELECT COUNT(*) AS count FROM (
SELECT DISTINCT COALESCE(p."packageGroupId", p."id") AS display_id
FROM packages p
${whereClause}
) AS display_items`,
`SELECT COUNT(*) AS count FROM packages p ${whereClause}`,
...params
);
const total = Number(countResult[0].count);
// Step 2: Get display item IDs for this page
// Step 2: Get package IDs for this page
const limitParam = paramIdx++;
const offsetParam = paramIdx++;
const displayRows = await prisma.$queryRawUnsafe<
{ display_id: string; display_type: string }[]
>(
`SELECT
COALESCE(p."packageGroupId", p."id") AS display_id,
CASE WHEN p."packageGroupId" IS NOT NULL THEN 'group' ELSE 'package' END AS display_type,
MAX(p.${sortCol}) AS sort_value
p."id" AS display_id,
'package' AS display_type,
p.${sortCol} AS sort_value
FROM packages p
${whereClause}
GROUP BY COALESCE(p."packageGroupId", p."id"),
CASE WHEN p."packageGroupId" IS NOT NULL THEN 'group' ELSE 'package' END
ORDER BY sort_value ${sortDir}
LIMIT $${limitParam} OFFSET $${offsetParam}`,
...params, limit, (page - 1) * limit