Files
halobestie-clone/backend/src/services/customer.service.js
ramadhan sjamsani 212e1e8ac6 Fix auth: auto-create customer, display name flow, OTP auto-verify
- Backend: getOrCreateCustomer with phone fallback for re-login
- Backend: PATCH /api/client/auth/profile for display name update
- Client app: AuthNeedsDisplayNameData state + SetDisplayNameScreen
- Client app: ApiClient.patch method
- Both apps: handle verificationCompleted for auto-verify (test numbers)
- Both apps: skip credential sign-in if already auto-verified
- Remove debug prints from mitra auth + OTP screens
- Fix ChatRequestNotifier.startListening skips when accepting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:22:28 +08:00

88 lines
3.2 KiB
JavaScript

import { getDb } from '../db/client.js'
const sql = getDb()
export const createAnonymousCustomer = async ({ display_name, firebase_uid }) => {
// Return existing customer if already linked to this Firebase UID
const [existing] = await sql`
SELECT id, display_name, is_anonymous, created_at
FROM customers WHERE firebase_uid = ${firebase_uid}
`
if (existing) return existing
const [customer] = await sql`
INSERT INTO customers (display_name, is_anonymous, firebase_uid)
VALUES (${display_name}, true, ${firebase_uid})
RETURNING id, display_name, is_anonymous, created_at
`
return customer
}
export const linkCustomerAccount = async ({ customer_id, firebase_uid }) => {
const [existing] = await sql`
SELECT id, firebase_uid FROM customers WHERE id = ${customer_id}
`
if (!existing) throw Object.assign(new Error('Customer not found'), { code: 'NOT_FOUND', statusCode: 404 })
if (existing.firebase_uid) throw Object.assign(new Error('Account already linked'), { code: 'ALREADY_REGISTERED', statusCode: 409 })
// Also fetch phone from firebase_uid if exists in another customer record for uniqueness
const [firebaseLinked] = await sql`
SELECT id FROM customers WHERE firebase_uid = ${firebase_uid}
`
if (firebaseLinked) throw Object.assign(new Error('Account already linked'), { code: 'ALREADY_REGISTERED', statusCode: 409 })
const [updated] = await sql`
UPDATE customers
SET firebase_uid = ${firebase_uid}, is_anonymous = false
WHERE id = ${customer_id}
RETURNING id, display_name, is_anonymous, phone, created_at
`
return updated
}
export const getCustomerByFirebaseUid = async (firebase_uid) => {
const [customer] = await sql`
SELECT id, display_name, is_anonymous, phone, created_at
FROM customers
WHERE firebase_uid = ${firebase_uid}
`
return customer
}
export const getOrCreateCustomer = async ({ firebase_uid, phone, display_name }) => {
// Return existing customer if already linked to this Firebase UID
const existing = await getCustomerByFirebaseUid(firebase_uid)
if (existing) return existing
// Check if a customer with this phone already exists (re-login with new Firebase UID)
if (phone) {
const [byPhone] = await sql`
SELECT id, display_name, is_anonymous, phone, created_at
FROM customers WHERE phone = ${phone}
`
if (byPhone) {
// Link the new Firebase UID to the existing phone-based customer
await sql`UPDATE customers SET firebase_uid = ${firebase_uid} WHERE id = ${byPhone.id}`
return { ...byPhone, firebase_uid }
}
}
// Auto-create a registered (non-anonymous) customer for phone/social login
// display_name is null — user must set it on first login
const [customer] = await sql`
INSERT INTO customers (firebase_uid, phone, display_name, is_anonymous)
VALUES (${firebase_uid}, ${phone || null}, ${display_name || null}, false)
RETURNING id, display_name, is_anonymous, phone, created_at
`
return customer
}
export const updateCustomerDisplayName = async (customerId, displayName) => {
const [customer] = await sql`
UPDATE customers SET display_name = ${displayName}
WHERE id = ${customerId}
RETURNING id, display_name, is_anonymous, phone, created_at
`
return customer
}