fix(inkop): stabil ordning i inkopslistan (id som tie-breaker + sortOrder pa nya varor)

Varor som lades till via recept/manuellt fick alla sortOrder=0. GET-listan
sorterade pa (sektion, sortOrder) utan stabil brytare, sa nar en rad bockades
av (UPDATE) kastades ordningen om - varorna hoppade. Nu: id som sista
sorteringsnyckel (total, deterministisk ordning) + nya varor far nasta
sortOrder sa de laggs sist.
This commit is contained in:
Claude
2026-08-19 16:50:18 +00:00
parent 0571234871
commit fcd5c7989f
+15 -1
View File
@@ -77,7 +77,14 @@ export async function shoppingRoutes(app: FastifyInstance) {
.select()
.from(schema.shoppingListItems)
.where(eq(schema.shoppingListItems.shoppingListId, id))
.orderBy(schema.shoppingListItems.storeSection, schema.shoppingListItems.sortOrder);
// Stabil ordning: sektion, sortOrder och SIST id som tie-breaker. Utan id
// hamnar rader med samma sortOrder (t.ex. alla 0) i odefinierad ordning som
// kastas om när en rad uppdateras (bockas av) varorna "hoppade" då runt.
.orderBy(
schema.shoppingListItems.storeSection,
schema.shoppingListItems.sortOrder,
schema.shoppingListItems.id,
);
const estimatedTotal = items.reduce((sum, i) => sum + (i.estimatedPriceMinor ?? 0), 0);
// Prisuppskattningar härleds ur katalogens baspriser (SEK) tills per-marknads-priser (M8).
return { list, items, estimatedTotalMinor: Math.round(estimatedTotal), currency: "SEK" };
@@ -139,6 +146,12 @@ export async function shoppingRoutes(app: FastifyInstance) {
}
}
// Nästa sortOrder = sist i listan, så nya varor läggs till på slutet i stället
// för att dela sortOrder 0 med alla andra (vilket gav ostabil ordning).
const [{ maxOrder } = { maxOrder: null }] = await app.db
.select({ maxOrder: sql<number | null>`max(${schema.shoppingListItems.sortOrder})` })
.from(schema.shoppingListItems)
.where(eq(schema.shoppingListItems.shoppingListId, id));
const [item] = await app.db
.insert(schema.shoppingListItems)
.values({
@@ -151,6 +164,7 @@ export async function shoppingRoutes(app: FastifyInstance) {
estimatedPriceMinor: estimatedPrice ?? null,
addedByUserId: req.userId,
origin: "manual",
sortOrder: (maxOrder ?? -1) + 1,
})
.returning();
return reply.status(201).send({ item, merged: false });