fix: stop prisma from dropping custom tables on every deploy

entrypoint.sh: removed --accept-data-loss from prisma db push.
That flag was silently dropping fs_users, fs_projects etc. on every
container restart, wiping all user/project data. Made the push
non-fatal so a schema mismatch doesn't block startup.

create/route.ts: fixed same broken ON CONFLICT expression as
authOptions.ts — replaced with explicit SELECT + INSERT/UPDATE
to reliably upsert fs_users before inserting the project.

Made-with: Cursor
This commit is contained in:
2026-02-27 19:15:55 -08:00
parent 8c3486dd58
commit 35675b7d86
2 changed files with 24 additions and 18 deletions

View File

@@ -24,22 +24,27 @@ export async function POST(request: Request) {
const workspace = email.split('@')[0].toLowerCase().replace(/[^a-z0-9]+/g, '-') + '-account'; const workspace = email.split('@')[0].toLowerCase().replace(/[^a-z0-9]+/g, '-') + '-account';
// Upsert user into fs_users — guarantees the FK target exists // Upsert user into fs_users — guarantees the FK target exists
await query(` const userData = JSON.stringify({
INSERT INTO fs_users (id, user_id, data)
VALUES (gen_random_uuid()::text, $1, $2::jsonb)
ON CONFLICT ((data->>'email')) DO UPDATE
SET user_id = EXCLUDED.user_id,
data = fs_users.data || EXCLUDED.data,
updated_at = NOW()
`, [
session.user.id,
JSON.stringify({
email, email,
name: session.user.name, name: session.user.name,
image: session.user.image, image: session.user.image,
workspace, workspace,
}), });
]); const existingUser = await query<{ id: string; data: any }>(
`SELECT id, data FROM fs_users WHERE data->>'email' = $1 LIMIT 1`,
[email]
);
if (existingUser.length === 0) {
await query(
`INSERT INTO fs_users (id, user_id, data) VALUES (gen_random_uuid()::text, $1, $2::jsonb)`,
[session.user.id, userData]
);
} else {
await query(
`UPDATE fs_users SET user_id = $1, data = data || $2::jsonb, updated_at = NOW() WHERE id = $3`,
[session.user.id, userData, existingUser[0].id]
);
}
// Fetch the canonical fs_users row (now guaranteed to exist) // Fetch the canonical fs_users row (now guaranteed to exist)
const users = await query<{ id: string; data: any }>(` const users = await query<{ id: string; data: any }>(`
@@ -47,7 +52,6 @@ export async function POST(request: Request) {
`, [email]); `, [email]);
const firebaseUserId = users[0]!.id; const firebaseUserId = users[0]!.id;
const userData = users[0]!.data || {};
const body = await request.json(); const body = await request.json();
const { const {

View File

@@ -2,7 +2,9 @@
set -e set -e
echo "=== Syncing NextAuth schema ===" echo "=== Syncing NextAuth schema ==="
npx prisma db push --accept-data-loss --skip-generate # NOTE: Do NOT use --accept-data-loss — it drops tables not in the Prisma schema,
# which destroys fs_users, fs_projects etc. Use --skip-generate only.
npx prisma db push --skip-generate || echo "Prisma push failed (non-fatal — tables may already be correct)"
echo "=== Ensuring app tables exist ===" echo "=== Ensuring app tables exist ==="
node -e " node -e "