Skip to content

Commit

Permalink
Merge pull request #1038 from jetstreamapp/chore/add-db-relationship-…
Browse files Browse the repository at this point in the history
…for-orgs-to-user

Add proper relationship from org to user
  • Loading branch information
paustint authored Oct 19, 2024
2 parents 14a8799 + 03d8f93 commit 3e3235b
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 15 deletions.
10 changes: 8 additions & 2 deletions apps/api/src/app/db/salesforce-org.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Maybe, SalesforceOrgUi } from '@jetstream/types';
import { Prisma, SalesforceOrg } from '@prisma/client';
import { parseISO } from 'date-fns/parseISO';
import isUndefined from 'lodash/isUndefined';
import { findIdByUserId } from './user.db';

const SELECT = Prisma.validator<Prisma.SalesforceOrgSelect>()({
jetstreamOrganizationId: true,
Expand Down Expand Up @@ -50,8 +51,9 @@ const findUniqueOrg = ({ jetstreamUserId, uniqueId }: { jetstreamUserId: string;
});
};

const findUsersOrgs = ({ jetstreamUserId }: { jetstreamUserId: string }) => {
const findUsersOrgs = ({ jetstreamUserId, actualUserId }: { jetstreamUserId: string; actualUserId: string }) => {
return Prisma.validator<Prisma.SalesforceOrgWhereInput>()({
jetstreamUserId2: actualUserId,
jetstreamUserId,
jetstreamUrl: ENV.JETSTREAM_SERVER_URL,
});
Expand Down Expand Up @@ -103,13 +105,15 @@ export async function findByUniqueId(jetstreamUserId: string, uniqueId: string)
}

export async function findByUserId(jetstreamUserId: string) {
const actualUserId = await findIdByUserId({ userId: jetstreamUserId });
return await prisma.salesforceOrg.findMany({
select: SELECT,
where: findUsersOrgs({ jetstreamUserId }),
where: findUsersOrgs({ jetstreamUserId, actualUserId }),
});
}

export async function createOrUpdateSalesforceOrg(jetstreamUserId: string, salesforceOrgUi: Partial<SalesforceOrgUi>) {
const actualUserId = await findIdByUserId({ userId: jetstreamUserId });
const existingOrg = await prisma.salesforceOrg.findUnique({
where: findUniqueOrg({ jetstreamUserId, uniqueId: salesforceOrgUi.uniqueId! }),
});
Expand All @@ -126,6 +130,7 @@ export async function createOrUpdateSalesforceOrg(jetstreamUserId: string, sales
orgToDelete = await prisma.salesforceOrg.findFirst({
select: { id: true },
where: {
jetstreamUserId2: { equals: actualUserId },
jetstreamUserId: { equals: jetstreamUserId },
jetstreamUrl: { equals: ENV.JETSTREAM_SERVER_URL! },
username: { equals: salesforceOrgUi.username },
Expand Down Expand Up @@ -178,6 +183,7 @@ export async function createOrUpdateSalesforceOrg(jetstreamUserId: string, sales
const org = await prisma.salesforceOrg.create({
select: SELECT,
data: {
jetstreamUserId2: actualUserId,
jetstreamUserId,
jetstreamUrl: ENV.JETSTREAM_SERVER_URL,
jetstreamOrganizationId: salesforceOrgUi.jetstreamOrganizationId,
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/app/db/user.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export async function createOrUpdateUser(user: UserProfileServer): Promise<{ cre
data: {
appMetadata: JSON.stringify(user._json[ENV.AUTH_AUDIENCE!]),
deletedAt: null,
lastLoggedIn: new Date(),
preferences: {
upsert: {
create: { skipFrontdoorLogin: false },
Expand All @@ -98,6 +99,7 @@ export async function createOrUpdateUser(user: UserProfileServer): Promise<{ cre
picture: user._json.picture,
appMetadata: JSON.stringify(user._json[ENV.AUTH_AUDIENCE!]),
deletedAt: null,
lastLoggedIn: new Date(),
preferences: { create: { skipFrontdoorLogin: false } },
},
select: userSelect,
Expand Down
31 changes: 30 additions & 1 deletion apps/api/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '@jetstream/api-config'; // this gets imported first to ensure as some items require early initialization
import { ENV, getExceptionLog, httpLogger, logger, pgPool } from '@jetstream/api-config';
import { ENV, getExceptionLog, httpLogger, logger, pgPool, prisma } from '@jetstream/api-config';
import { HTTP, SESSION_EXP_DAYS } from '@jetstream/shared/constants';
import { Maybe } from '@jetstream/types';
import { json, raw, urlencoded } from 'body-parser';
Expand Down Expand Up @@ -364,3 +364,32 @@ if (ENV.NODE_ENV === 'production' && cluster.isPrimary) {
logger.error(getExceptionLog(error), '[SERVER][ERROR]');
});
}

if (ENV.EXAMPLE_USER_OVERRIDE && ENV.EXAMPLE_USER && (ENV.ENVIRONMENT !== 'production' || ENV.IS_CI)) {
const id = 'AAAAAAAA-0000-0000-0000-AAAAAAAAAAAA';
logger.info('Upserting example user. id: %s', id);
prisma.user
.upsert({
create: {
id,
userId: ENV.EXAMPLE_USER.user_id,
email: ENV.EXAMPLE_USER._json.email,
name: ENV.EXAMPLE_USER._json.name,
nickname: ENV.EXAMPLE_USER._json.nickname,
picture: ENV.EXAMPLE_USER._json.picture,
appMetadata: JSON.stringify(ENV.EXAMPLE_USER._json[ENV.AUTH_AUDIENCE!]),
deletedAt: null,
lastLoggedIn: new Date(),
preferences: { create: { skipFrontdoorLogin: false } },
},
update: {},
where: { id },
})
.then(() => {
logger.info('Example user created');
})
.catch((ex) => {
logger.error(getExceptionLog(ex), '[EXAMPLE_USER][ERROR] Fatal error, could not create example user');
process.exit(1);
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "lastLoggedIn" TIMESTAMP(3);

-- AlterTable
ALTER TABLE "salesforce_org" ADD COLUMN "jetstreamUserId2" UUID;

UPDATE salesforce_org
SET "jetstreamUserId2" = u.id
FROM "User" u
WHERE salesforce_org."jetstreamUserId" = u."userId";

-- AddForeignKey
ALTER TABLE "salesforce_org" ADD CONSTRAINT "salesforce_org_jetstreamUserId2_fkey" FOREIGN KEY ("jetstreamUserId2") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
28 changes: 16 additions & 12 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ datasource db {
}

model User {
id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
userId String @unique @db.VarChar
email String @db.VarChar
name String? @db.VarChar
nickname String? @db.VarChar
picture String? @db.VarChar
appMetadata Json? @db.Json
preferences UserPreference?
organizations JetstreamOrganization[]
deletedAt DateTime?
createdAt DateTime @default(now()) @db.Timestamp(6)
updatedAt DateTime @updatedAt
id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
userId String @unique @db.VarChar
email String @db.VarChar
name String? @db.VarChar
nickname String? @db.VarChar
picture String? @db.VarChar
appMetadata Json? @db.Json
preferences UserPreference?
salesforceOrgs SalesforceOrg[]
organizations JetstreamOrganization[]
lastLoggedIn DateTime?
deletedAt DateTime?
createdAt DateTime @default(now()) @db.Timestamp(6)
updatedAt DateTime @updatedAt
}

model UserPreference {
Expand Down Expand Up @@ -63,6 +65,8 @@ model SalesforceApi {
model SalesforceOrg {
id Int @id @default(autoincrement())
jetstreamUserId String @db.VarChar
jetstreamUser User? @relation(fields: [jetstreamUserId2], references: [id], onDelete: Cascade)
jetstreamUserId2 String? @db.Uuid
jetstreamOrganization JetstreamOrganization? @relation(fields: [jetstreamOrganizationId], references: [id])
jetstreamOrganizationId String? @db.Uuid
uniqueId String @db.VarChar
Expand Down

0 comments on commit 3e3235b

Please sign in to comment.