Implement lists module and dev login setup

This commit is contained in:
ginnoir
2026-05-06 03:49:03 -05:00
parent 744c1119a9
commit 7e3ae6eb04
31 changed files with 1525 additions and 63 deletions
+2
View File
@@ -11,6 +11,7 @@ import {
} from "@/modules/_core/schema";
import { eq } from "drizzle-orm";
import { ensureDefaultCalendarsForMembership } from "@/modules/calendar/server/defaults";
import { ensureDefaultListsForHousehold } from "@/modules/lists/server/defaults";
declare module "next-auth" {
interface Session {
@@ -64,6 +65,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
householdId: household.id,
userId: user.id,
});
await ensureDefaultListsForHousehold(household.id);
}
}
return true;
+2 -1
View File
@@ -2,9 +2,10 @@ import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as coreSchema from "@/modules/_core/schema";
import * as calendarSchema from "@/modules/calendar/schema";
import * as listsSchema from "@/modules/lists/schema";
const client = postgres(process.env["DATABASE_URL"]!);
const schema = { ...coreSchema, ...calendarSchema };
const schema = { ...coreSchema, ...calendarSchema, ...listsSchema };
export const db = drizzle(client, { schema });
+5
View File
@@ -0,0 +1,5 @@
export const DEV_LOGIN_COOKIE = "authjs.session-token";
export function isDevLoginEnabled() {
return process.env.NODE_ENV !== "production" && process.env.ENABLE_DEV_LOGIN === "true";
}
+79
View File
@@ -0,0 +1,79 @@
import { randomBytes } from "node:crypto";
import { and, eq } from "drizzle-orm";
import { db } from "@/lib/db";
import { ensureDefaultCalendarsForMembership } from "@/modules/calendar/server/defaults";
import { households, householdMembers, sessions, users } from "@/modules/_core/schema";
import { ensureDefaultListsForHousehold } from "@/modules/lists/server/defaults";
import { isDevLoginEnabled } from "./dev-login-config";
export async function createDevSession() {
if (!isDevLoginEnabled()) throw new Error("Dev login is disabled");
const email = process.env.DEV_LOGIN_EMAIL ?? "dev@famapp.local";
const name = process.env.DEV_LOGIN_NAME ?? "Dev User";
const householdName = process.env.DEV_HOUSEHOLD_NAME ?? "Home";
const [existingHousehold] = await db
.select()
.from(households)
.where(eq(households.name, householdName))
.limit(1);
const resolvedHousehold =
existingHousehold ??
(await db.insert(households).values({ name: householdName }).returning())[0];
if (!resolvedHousehold) throw new Error("Dev household was not created");
const [user] = await db.insert(users).values({ email, name }).onConflictDoNothing().returning();
const resolvedUser =
user ?? (await db.select().from(users).where(eq(users.email, email)).limit(1))[0];
if (!resolvedUser) throw new Error("Dev user was not created");
const [anyMember] = await db
.select()
.from(householdMembers)
.where(eq(householdMembers.householdId, resolvedHousehold.id))
.limit(1);
await db
.insert(householdMembers)
.values({
householdId: resolvedHousehold.id,
userId: resolvedUser.id,
role: anyMember ? "member" : "owner",
})
.onConflictDoNothing();
const [membership] = await db
.select()
.from(householdMembers)
.where(
and(
eq(householdMembers.householdId, resolvedHousehold.id),
eq(householdMembers.userId, resolvedUser.id),
),
)
.limit(1);
if (!membership) throw new Error("Dev membership was not created");
await ensureDefaultCalendarsForMembership({
householdId: resolvedHousehold.id,
userId: resolvedUser.id,
});
await ensureDefaultListsForHousehold(resolvedHousehold.id);
const sessionToken = randomBytes(32).toString("base64url");
const expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
await db.insert(sessions).values({
sessionToken,
userId: resolvedUser.id,
expires,
});
return { sessionToken, expires };
}