mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
refactor( iam ): replace userId FK with iamUserId on UserPreferences, Device, FraudAlert
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
-- Drop FK constraints (they reference iam.users indirectly via local User, but these are within passenger schema)
|
||||
ALTER TABLE passenger."UserPreferences" DROP CONSTRAINT IF EXISTS "UserPreferences_userId_fkey";
|
||||
ALTER TABLE passenger."Device" DROP CONSTRAINT IF EXISTS "Device_userId_fkey";
|
||||
ALTER TABLE passenger."FraudAlert" DROP CONSTRAINT IF EXISTS "FraudAlert_userId_fkey";
|
||||
|
||||
-- Rename columns (preserves all existing data)
|
||||
ALTER TABLE passenger."UserPreferences" RENAME COLUMN "userId" TO "iamUserId";
|
||||
ALTER TABLE passenger."Device" RENAME COLUMN "userId" TO "iamUserId";
|
||||
ALTER TABLE passenger."FraudAlert" RENAME COLUMN "userId" TO "iamUserId";
|
||||
|
||||
-- Rename indexes on FraudAlert to match new column name
|
||||
DROP INDEX IF EXISTS passenger."FraudAlert_userId_createdAt_idx";
|
||||
CREATE INDEX "FraudAlert_iamUserId_createdAt_idx" ON passenger."FraudAlert"("iamUserId", "createdAt");
|
||||
@@ -232,10 +232,7 @@ model User {
|
||||
passenger Passenger?
|
||||
agent Agent?
|
||||
sessions Session[]
|
||||
devices Device[]
|
||||
preferences UserPreferences?
|
||||
auditLogs AuditLog[]
|
||||
fraudAlerts FraudAlert[]
|
||||
|
||||
faydaVerificationSessions FaydaVerificationSession[]
|
||||
|
||||
@@ -870,7 +867,7 @@ model SupportMessage {
|
||||
|
||||
model UserPreferences {
|
||||
id String @id @default(uuid())
|
||||
userId String @unique
|
||||
iamUserId String @unique
|
||||
pushEnabled Boolean @default(true)
|
||||
emailEnabled Boolean @default(true)
|
||||
smsEnabled Boolean @default(false)
|
||||
@@ -883,20 +880,18 @@ model UserPreferences {
|
||||
locale String @default("en")
|
||||
darkMode Boolean @default(false)
|
||||
language String @default("en")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@schema("passenger")
|
||||
}
|
||||
|
||||
model Device {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
iamUserId String
|
||||
platform DevicePlatform
|
||||
name String
|
||||
pushToken String?
|
||||
trusted Boolean @default(false)
|
||||
lastSeenAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@schema("passenger")
|
||||
}
|
||||
@@ -1222,15 +1217,14 @@ model FraudRule {
|
||||
|
||||
model FraudAlert {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
iamUserId String
|
||||
eventType String
|
||||
triggeredRules String[]
|
||||
context Json
|
||||
severity String @default("MEDIUM")
|
||||
acknowledged Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
@@index([userId, createdAt])
|
||||
@@index([iamUserId, createdAt])
|
||||
@@index([acknowledged])
|
||||
|
||||
@@schema("passenger")
|
||||
|
||||
@@ -192,7 +192,7 @@ export class PassengerAuthService {
|
||||
});
|
||||
await tx.loyaltyAccount.create({ data: { passengerId: passenger.id } });
|
||||
await tx.walletAccount.create({ data: { passengerId: passenger.id } });
|
||||
await tx.userPreferences.create({ data: { userId: user.id } });
|
||||
await tx.userPreferences.create({ data: { iamUserId: data.iamUserId } });
|
||||
await tx.auditLog.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
|
||||
@@ -106,22 +106,22 @@ export class BookingsService {
|
||||
const { search, status, page = 1, pageSize = 20 } = filters;
|
||||
const skip = (page - 1) * pageSize;
|
||||
|
||||
// Find user with this device ID
|
||||
const device = await this.prisma.device.findUnique({
|
||||
where: { id: deviceId },
|
||||
include: { user: { include: { passenger: true } } },
|
||||
}).catch(() => null);
|
||||
|
||||
// Find passenger linked to this device via iamUserId
|
||||
const device = await this.prisma.device.findUnique({ where: { id: deviceId } }).catch(() => null);
|
||||
const passenger = device?.iamUserId
|
||||
? await this.prisma.passenger.findUnique({ where: { iamUserId: device.iamUserId } }).catch(() => null)
|
||||
: null;
|
||||
|
||||
const searchConditions = search ? [
|
||||
{ bookingRef: { contains: search, mode: 'insensitive' } },
|
||||
{ schedule: { originStation: { name: { contains: search, mode: 'insensitive' } } } },
|
||||
{ schedule: { destinationStation: { name: { contains: search, mode: 'insensitive' } } } },
|
||||
] : [];
|
||||
|
||||
|
||||
const where: any = {
|
||||
OR: [
|
||||
{ userAgent: deviceId },
|
||||
...(device?.user?.passenger ? [{ passengerId: device.user.passenger.id }] : []),
|
||||
...(passenger ? [{ passengerId: passenger.id }] : []),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ export class FraudService {
|
||||
): Promise<void> {
|
||||
const alert = await this.prisma.fraudAlert.create({
|
||||
data: {
|
||||
userId,
|
||||
iamUserId: userId,
|
||||
eventType,
|
||||
triggeredRules,
|
||||
context: context as any,
|
||||
@@ -182,7 +182,7 @@ export class FraudService {
|
||||
*/
|
||||
async getAlerts(userId?: string, limit = 100, offset = 0) {
|
||||
return this.prisma.fraudAlert.findMany({
|
||||
where: userId ? { userId } : {},
|
||||
where: userId ? { iamUserId: userId } : {},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: limit,
|
||||
skip: offset,
|
||||
|
||||
@@ -166,20 +166,21 @@ export class NotificationsService {
|
||||
|
||||
private async getUserPreferredChannels(recipient: string): Promise<NotificationChannelType[]> {
|
||||
const user = await this.prisma.user.findFirst({
|
||||
where: {
|
||||
OR: [{ id: recipient }, { email: recipient }, { phone: recipient }],
|
||||
},
|
||||
include: { preferences: true },
|
||||
where: { OR: [{ id: recipient }, { email: recipient }, { phone: recipient }] },
|
||||
include: { passenger: { select: { iamUserId: true } } },
|
||||
});
|
||||
|
||||
if (!user?.preferences) {
|
||||
const iamUserId = user?.passenger?.iamUserId ?? recipient;
|
||||
const preferences = await this.prisma.userPreferences.findUnique({ where: { iamUserId } });
|
||||
|
||||
if (!preferences) {
|
||||
return ['IN_APP', 'EMAIL'];
|
||||
}
|
||||
|
||||
const channels: NotificationChannelType[] = ['IN_APP'];
|
||||
if (user.preferences.emailEnabled) channels.push('EMAIL');
|
||||
if (user.preferences.smsEnabled) channels.push('SMS');
|
||||
if (user.preferences.pushEnabled) channels.push('PUSH');
|
||||
if (preferences.emailEnabled) channels.push('EMAIL');
|
||||
if (preferences.smsEnabled) channels.push('SMS');
|
||||
if (preferences.pushEnabled) channels.push('PUSH');
|
||||
|
||||
return channels;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user