Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ next-env.d.ts

## supabase
/supabase/
.qodo
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,27 @@ pnpm db:regenerate-migrations
If this worked, you should see 5 triggers in Supabase under [Database > Triggers > auth](https://supabase.com/dashboard/project/pboorlggoqpyiucxmneq/database/triggers?schema=auth).

Also, make sure you delete your Supabase users under Authentication, as those are no longer duplicated in the `UserProfile` table.

## Dynamic Database Credentials with Vercel

This project supports dynamic database credentials, making it easy to change the database user without modifying the code.

### Local Setup
1. Set `POSTGRES_USER` and `POSTGRES_PASSWORD` in your `.env` file
2. Run migrations with `npm run db:migrate:prod`

### Vercel Setup
1. Add the following environment variables in your Vercel project:
- `POSTGRES_USER`: Your database user (e.g., "prisma" or any custom user)
- `POSTGRES_PASSWORD`: Your database password

2. Update the build command in your Vercel project to use the migration script:
```
npm run build && npm run db:migrate:prod
```

3. When you need to change database credentials:
- Update the `POSTGRES_USER` and `POSTGRES_PASSWORD` environment variables in Vercel
- Redeploy your application

This approach allows you to change database credentials without modifying the codebase, migration files, or prisma schema.
6 changes: 3 additions & 3 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export default function Login() {
try {
setIsLoading(true);

const { url } = await loginMutation.mutateAsync({ authProviderType: "GOOGLE" });
const { data } = await loginMutation.mutateAsync({ authProviderType: "GOOGLE" });

if (url) {
if (data) {
// Redirect to Google's OAuth page
window.location.href = url
window.location.href = data
} else {
console.error("No URL returned from authenticate")
setIsLoading(false);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
"db:migrate": "prisma migrate dev",
"seed": "node -r ts-node/register --env-file=.env prisma/seed.ts",
"postinstall": "npx prisma generate",
"db:postinstall": "prisma generate && prisma migrate deploy",
"db:postinstall": "prisma generate && ./scripts/migrate-db.sh",
"db:regenerate-migrations": "./scripts/regenerate-prisma-migrations.sh",
"db:migrate:prod": "./scripts/migrate-db.sh",
"sdk:dev": "tsup --watch",
"sdk:build": "tsup"
},
Expand Down
47 changes: 45 additions & 2 deletions prisma/migrations/20250224065512_session_trigger/migration.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,52 @@ SET search_path = public
AS $$
DECLARE
country_code VARCHAR(2);
user_exists BOOLEAN;
BEGIN
INSERT INTO "Sessions" (id, "createdAt", "updatedAt", ip, "userAgent", "userId", "deviceNonce")
SELECT NEW.id, NEW.created_at, NEW.updated_at, NEW.ip, NEW.user_agent, NEW.user_id, gen_random_uuid();
-- Check if the user exists in UserProfiles
SELECT EXISTS (
SELECT 1 FROM "UserProfiles" WHERE "supId" = NEW.user_id
) INTO user_exists;

-- If user doesn't exist in UserProfiles, try to create it from auth.users
IF NOT user_exists THEN
BEGIN
INSERT INTO "UserProfiles" ("supId", "supEmail", "name", "email", "updatedAt")
SELECT
u.id,
u.email,
COALESCE(u.raw_user_meta_data->>'full_name', u.raw_user_meta_data->>'name'),
u.email,
NOW()
FROM auth.users u
WHERE u.id = NEW.user_id
ON CONFLICT ("supId") DO NOTHING;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Failed to create user profile: %', SQLERRM;
-- Continue anyway, as the user might be created in another concurrent transaction
END;
END IF;

-- Double-check that user exists before creating session
SELECT EXISTS (
SELECT 1 FROM "UserProfiles" WHERE "supId" = NEW.user_id
) INTO user_exists;

IF user_exists THEN
-- Now create the session (should work since user exists)
BEGIN
INSERT INTO "Sessions" (id, "createdAt", "updatedAt", ip, "userAgent", "userId", "deviceNonce")
SELECT NEW.id, NEW.created_at, NEW.updated_at, NEW.ip, NEW.user_agent, NEW.user_id, gen_random_uuid();
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Failed to create session: %', SQLERRM;
-- Log error but don't fail the transaction
END;
ELSE
RAISE NOTICE 'Cannot create session: User % does not exist in UserProfiles', NEW.user_id;
END IF;

RETURN NULL;
END;
$$;
Expand Down
Loading