fix(household): join tar bort tomt auto-sol-hushåll så delat hushåll blir aktivt (MIKRO 58)
CI / Typecheck, test & build (push) Failing after 43s

This commit is contained in:
Sven (AAMOS AI)
2026-08-14 20:00:49 +07:00
parent 1e6407d9e6
commit 9bd827a90d
3 changed files with 41 additions and 1 deletions
+31
View File
@@ -83,6 +83,37 @@ export async function createHouseholdWithDefaults(
return { id: household!.id, name: household!.name };
}
/** När en användare går med i ett annat hushåll: ta bort deras auto-skapade
* sol-hushåll (enda ägaren, inget lager) så det delade blir aktivt. */
export async function discardEmptySoloHouseholds(
db: Database,
userId: string,
keepHouseholdId: string,
): Promise<void> {
const memberships = await db
.select({
householdId: schema.householdMembers.householdId,
role: schema.householdMembers.role,
})
.from(schema.householdMembers)
.where(eq(schema.householdMembers.userId, userId));
for (const m of memberships) {
if (m.householdId === keepHouseholdId || m.role !== "owner") continue;
const members = await db
.select({ userId: schema.householdMembers.userId })
.from(schema.householdMembers)
.where(eq(schema.householdMembers.householdId, m.householdId));
if (members.length !== 1) continue; // inte ensam medlem → rör inte
const [inv] = await db
.select({ id: schema.inventoryItems.id })
.from(schema.inventoryItems)
.where(eq(schema.inventoryItems.householdId, m.householdId))
.limit(1);
if (inv) continue; // har lager → rör inte
await db.delete(schema.households).where(eq(schema.households.id, m.householdId)); // cascade städar medlem + platser
}
}
/** Hämta användarens aktiva hushåll (första medlemskapet) eller null. */
export async function getActiveHouseholdId(db: Database, userId: string): Promise<string | null> {
const [member] = await db
+3
View File
@@ -16,6 +16,7 @@ import { errors, parse } from "../lib/errors.js";
import {
audit,
createHouseholdWithDefaults,
discardEmptySoloHouseholds,
emitEvent,
generateInviteCode,
requireMembership,
@@ -142,6 +143,8 @@ export async function householdRoutes(app: FastifyInstance) {
.values({ householdId: household.id, userId: req.userId, role: "adult" })
.onConflictDoNothing();
await discardEmptySoloHouseholds(app.db, req.userId, household.id);
await emitEvent(app.db, {
type: "HOUSEHOLD_MEMBER_ADDED",
payload: { householdId: household.id, newUserId: req.userId, role: "adult" },
+7 -1
View File
@@ -4,7 +4,12 @@ import { z } from "zod";
import { schema } from "@app/database";
import { quickStartInputSchema, onboardingInputSchema } from "@app/validation";
import { errors, parse } from "../lib/errors.js";
import { audit, createHouseholdWithDefaults, getActiveHouseholdId } from "../lib/helpers.js";
import {
audit,
createHouseholdWithDefaults,
discardEmptySoloHouseholds,
getActiveHouseholdId,
} from "../lib/helpers.js";
import { t } from "../lib/i18n.js";
import { KNOWN_FLAGS } from "@app/feature-flags";
@@ -171,6 +176,7 @@ export async function onboardingRoutes(app: FastifyInstance) {
.insert(schema.householdMembers)
.values({ householdId: household.id, userId: req.userId, role: "adult" })
.onConflictDoNothing();
await discardEmptySoloHouseholds(app.db, req.userId, household.id);
householdId = household.id;
}