Add household seeding & session (task 07)
- scripts/seed.ts: idempotent pnpm db:seed inserts "Home" household if none exists (powered by tsx)
- signIn callback: first member of household gets owner role, subsequent users get member
- src/lib/session.ts: getCurrentSession() returns { user, household, role }, throws if unauthenticated or unmembered
- /settings/household: member list for all roles; rename form gated to owner only (server action also enforces)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5da472d6ff
commit
6710c8b231
+7
-3
@@ -41,8 +41,6 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
|
||||
callbacks: {
|
||||
async signIn({ user }) {
|
||||
if (!user.id) return true;
|
||||
// Attach user to the single household if not already a member.
|
||||
// (Household is seeded by task 07; this is a no-op until then.)
|
||||
const existing = await db
|
||||
.select()
|
||||
.from(householdMembers)
|
||||
@@ -51,9 +49,15 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
|
||||
if (existing.length === 0) {
|
||||
const [household] = await db.select().from(households).limit(1);
|
||||
if (household) {
|
||||
const [anyMember] = await db
|
||||
.select()
|
||||
.from(householdMembers)
|
||||
.where(eq(householdMembers.householdId, household.id))
|
||||
.limit(1);
|
||||
const role = anyMember ? "member" : "owner";
|
||||
await db
|
||||
.insert(householdMembers)
|
||||
.values({ householdId: household.id, userId: user.id })
|
||||
.values({ householdId: household.id, userId: user.id, role })
|
||||
.onConflictDoNothing();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { db } from "@/lib/db";
|
||||
import { householdMembers, households, users } from "@/modules/_core/schema";
|
||||
|
||||
export interface CurrentSession {
|
||||
user: typeof users.$inferSelect;
|
||||
household: typeof households.$inferSelect;
|
||||
role: "owner" | "member";
|
||||
}
|
||||
|
||||
export async function getCurrentSession(): Promise<CurrentSession> {
|
||||
const session = await auth();
|
||||
if (!session?.user?.id) throw new Error("Not authenticated");
|
||||
|
||||
const [row] = await db
|
||||
.select({
|
||||
user: users,
|
||||
household: households,
|
||||
role: householdMembers.role,
|
||||
})
|
||||
.from(householdMembers)
|
||||
.innerJoin(users, eq(householdMembers.userId, users.id))
|
||||
.innerJoin(households, eq(householdMembers.householdId, households.id))
|
||||
.where(eq(householdMembers.userId, session.user.id))
|
||||
.limit(1);
|
||||
|
||||
if (!row) throw new Error("No household membership");
|
||||
|
||||
return row;
|
||||
}
|
||||
Reference in New Issue
Block a user