From 939597481e713748020233d779e68a0b20f73d70 Mon Sep 17 00:00:00 2001 From: Roy Scheeren Date: Wed, 31 Jan 2024 14:10:24 +0100 Subject: [PATCH 1/4] feat(envited.ascs.digital): wip Signed-off-by: Roy Scheeren --- .../common/constants/index.ts | 1 + .../common/database/schema.ts | 10 ++- .../common/guards/guards.test.ts | 21 ++++++ .../common/guards/guards.ts | 5 +- .../common/guards/index.ts | 2 +- .../common/serverActions/profiles/get.test.ts | 73 +++++++++++++++++++ .../common/serverActions/profiles/get.ts | 49 +++++++++++++ .../common/serverActions/profiles/index.ts | 1 + 8 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts create mode 100644 apps/envited.ascs.digital/common/serverActions/profiles/get.ts diff --git a/apps/envited.ascs.digital/common/constants/index.ts b/apps/envited.ascs.digital/common/constants/index.ts index 7deebc7a..619b5839 100644 --- a/apps/envited.ascs.digital/common/constants/index.ts +++ b/apps/envited.ascs.digital/common/constants/index.ts @@ -3,3 +3,4 @@ export { RESPONSES } from './response' export { NAVIGATION_DASHBOARD } from './navigations' export const MINIMUM_PROFILE_REQUIREMENTS = ['name', 'category', 'logo', 'description'] +export const RESTRICTED_PROFILE_FIELDS = ['principalName', 'principalPhone', 'principalEmail'] diff --git a/apps/envited.ascs.digital/common/database/schema.ts b/apps/envited.ascs.digital/common/database/schema.ts index 39ea7a35..3600d475 100644 --- a/apps/envited.ascs.digital/common/database/schema.ts +++ b/apps/envited.ascs.digital/common/database/schema.ts @@ -124,10 +124,12 @@ export const profile = pgTable('profile', { postalCode: text('postal_code'), addressLocality: text('address_locality'), addressCountry: text('address_country'), - firstName: text('first_name'), - lastName: text('last_name'), - phone: text('phone'), - email: text('email'), + salesName: text('sales_name'), + salesPhone: text('sales_phone'), + salesEmail: text('sales_email'), + principalName: text('principal_name'), + principalPhone: text('principal_phone'), + principalEmail: text('principal_email'), website: text('website'), offerings: jsonb('offerings'), isPublished: boolean('is_published').default(false), diff --git a/apps/envited.ascs.digital/common/guards/guards.test.ts b/apps/envited.ascs.digital/common/guards/guards.test.ts index 38eb7014..8f110140 100644 --- a/apps/envited.ascs.digital/common/guards/guards.test.ts +++ b/apps/envited.ascs.digital/common/guards/guards.test.ts @@ -101,4 +101,25 @@ describe('common/guards', () => { expect(result).toEqual(true) }) }) + + describe('isUsersCompanyProfile', () => { + it('should check if the requested profile is the profile of the logged in users company', () => { + // when ... we want to check if the requested profile is owned by the logged in users company + // then ... we should get the result as expected + const principal = { + id: 'PKH', + name: 'NAME', + profile: { + name: 'NAME', + }, + } as any + + const profile = { + name: 'NAME', + } as any + const result = SUT.isUsersCompanyProfile(principal)(profile) + + expect(result).toEqual(true) + }) + }) }) diff --git a/apps/envited.ascs.digital/common/guards/guards.ts b/apps/envited.ascs.digital/common/guards/guards.ts index ab046f09..72145793 100644 --- a/apps/envited.ascs.digital/common/guards/guards.ts +++ b/apps/envited.ascs.digital/common/guards/guards.ts @@ -12,5 +12,8 @@ export const isOwnUser = (user: User) => (session: Session) => export const userIsIssuedByLoggedInUser = (user: User) => (session: Session) => equals(prop('issuerId')(user))(pathOr('', ['user', 'pkh'])(session)) -export const isOwnProfile = (user: User) => (profile: { name?: string }) => +export const isOwnProfile = (user: User) => (profile: { name: string }) => equals(path(['profile', 'name'])(user))(prop('name')(profile)) + +export const isUsersCompanyProfile = (principal: User) => (profile: { name: string }) => + equals(prop('name')(principal))(prop('name')(profile)) diff --git a/apps/envited.ascs.digital/common/guards/index.ts b/apps/envited.ascs.digital/common/guards/index.ts index 5ba1768f..513287a2 100644 --- a/apps/envited.ascs.digital/common/guards/index.ts +++ b/apps/envited.ascs.digital/common/guards/index.ts @@ -1 +1 @@ -export { isFederator, isOwnUser, isOwnProfile, isPrincipal, userIsIssuedByLoggedInUser } from './guards' +export { isFederator, isOwnUser, isOwnProfile, isPrincipal, userIsIssuedByLoggedInUser, isUsersCompanyProfile } from './guards' diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts b/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts new file mode 100644 index 00000000..941bed00 --- /dev/null +++ b/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts @@ -0,0 +1,73 @@ +import { Role } from '../../types' +import * as SUT from './get' + +describe('serverActions/profiles/get', () => { + describe('get', () => { + it('should get the profile as expected', async () => { + // when ... we want to get the full profile for a principal user + // then ... it should get the profile as expected + const getServerSessionStub = jest.fn().mockResolvedValue({ + user: { + id: 'USER_PKH', + role: Role.principal, + }, + }) + + const dbStub = jest.fn().mockResolvedValue({ + getProfileById: jest.fn().mockResolvedValue({ + name: 'USER_NAME', + description: 'USER_DESCRIPTION', + principalName: 'USER_PRINCIPAL_NAME', + }), + getUserById: jest.fn().mockResolvedValue({ + name: 'USER_NAME', + profile: { + name: 'USER_NAME', + }, + }), + }) + + const id = 'PROFILE_ID' + + const result = await SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(id) + const db = await dbStub() + expect(result).toEqual({ + name: 'USER_NAME', + description: 'USER_DESCRIPTION', + principalName: 'USER_PRINCIPAL_NAME' + }) + expect(getServerSessionStub).toHaveBeenCalledWith() + expect(db.getProfileById).toHaveBeenCalledWith(id) + expect(db.getUserById).toHaveBeenCalledWith('USER_PKH') + }) + + it('should return a limited profile when there is no session', async () => { + // when ... we want to get the limited profile for a principal user + // then ... it should get the profile as expected + const getServerSessionStub = jest.fn().mockResolvedValue(null) + + const dbStub = jest.fn().mockResolvedValue({ + getProfileById: jest.fn().mockResolvedValue({ + name: 'USER_NAME', + description: 'USER_DESCRIPTION', + principalName: 'USER_PRINCIPAL_NAME', + }), + getUserById: jest.fn().mockResolvedValue({ + name: 'USER_NAME', + profile: { + name: 'USER_NAME', + }, + }), + }) + + const id = 'PROFILE_ID' + + const result = await SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(id) + + expect(result).toEqual({ + name: 'USER_NAME', + description: 'USER_DESCRIPTION', + }) + }) + }) +}) diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/get.ts b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts new file mode 100644 index 00000000..7654faf2 --- /dev/null +++ b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts @@ -0,0 +1,49 @@ +'use server' + +import { error } from 'console'; +import { getServerSession } from '../../auth' +import { db } from '../../database/queries' +import { Database } from '../../database/types'; +import { Session } from '../../types'; +import { isEmpty, isNil, omit } from 'ramda'; +import { RESTRICTED_PROFILE_FIELDS } from '../../constants'; +import { badRequestError, notFoundError } from '../../utils'; +import { isOwnProfile, isUsersCompanyProfile } from '../../guards'; + +export const _get = + ({ db, getServerSession }: { db: Database; getServerSession: () => Promise }) => + async (id: string) => { + try { + if (isNil(id) || isEmpty(id)) { + throw badRequestError('Missing profile id') + } + + const session = await getServerSession() + const connection = await db() + const profile = await connection.getProfileById(id) + + if (isNil(profile) || isEmpty(profile)) { + throw notFoundError() + } + + if (!isNil(session)) { + const user = await connection.getUserById(session.user.id) + + if (isOwnProfile(user)(profile)) { + return profile + } + + const principal = await connection.getPrincipalByUserId(user.id) + if (isUsersCompanyProfile(principal)(profile)) { + return profile + } + } + + return omit(RESTRICTED_PROFILE_FIELDS)(profile) + } catch (e) { + console.log('error', e) + throw error() + } + } + +export const get = _get({ db, getServerSession }) diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/index.ts b/apps/envited.ascs.digital/common/serverActions/profiles/index.ts index bcf0f24a..5c5c011d 100644 --- a/apps/envited.ascs.digital/common/serverActions/profiles/index.ts +++ b/apps/envited.ascs.digital/common/serverActions/profiles/index.ts @@ -1 +1,2 @@ export { update as updateProfile } from './update' +export { get as getProfile } from './get' From 8f36504c11fc8bf45dc0de078865c2b33b21efbc Mon Sep 17 00:00:00 2001 From: Roy Scheeren Date: Wed, 31 Jan 2024 14:10:35 +0100 Subject: [PATCH 2/4] feat(envited.ascs.digital): wip Signed-off-by: Roy Scheeren --- .../envited.ascs.digital/common/guards/index.ts | 9 ++++++++- .../common/serverActions/profiles/get.test.ts | 2 +- .../common/serverActions/profiles/get.ts | 17 +++++++++-------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/apps/envited.ascs.digital/common/guards/index.ts b/apps/envited.ascs.digital/common/guards/index.ts index 513287a2..8e8647a8 100644 --- a/apps/envited.ascs.digital/common/guards/index.ts +++ b/apps/envited.ascs.digital/common/guards/index.ts @@ -1 +1,8 @@ -export { isFederator, isOwnUser, isOwnProfile, isPrincipal, userIsIssuedByLoggedInUser, isUsersCompanyProfile } from './guards' +export { + isFederator, + isOwnUser, + isOwnProfile, + isPrincipal, + userIsIssuedByLoggedInUser, + isUsersCompanyProfile, +} from './guards' diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts b/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts index 941bed00..665415ec 100644 --- a/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts +++ b/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts @@ -34,7 +34,7 @@ describe('serverActions/profiles/get', () => { expect(result).toEqual({ name: 'USER_NAME', description: 'USER_DESCRIPTION', - principalName: 'USER_PRINCIPAL_NAME' + principalName: 'USER_PRINCIPAL_NAME', }) expect(getServerSessionStub).toHaveBeenCalledWith() expect(db.getProfileById).toHaveBeenCalledWith(id) diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/get.ts b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts index 7654faf2..3e289b18 100644 --- a/apps/envited.ascs.digital/common/serverActions/profiles/get.ts +++ b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts @@ -1,14 +1,15 @@ 'use server' -import { error } from 'console'; +import { error } from 'console' +import { isEmpty, isNil, omit } from 'ramda' + import { getServerSession } from '../../auth' +import { RESTRICTED_PROFILE_FIELDS } from '../../constants' import { db } from '../../database/queries' -import { Database } from '../../database/types'; -import { Session } from '../../types'; -import { isEmpty, isNil, omit } from 'ramda'; -import { RESTRICTED_PROFILE_FIELDS } from '../../constants'; -import { badRequestError, notFoundError } from '../../utils'; -import { isOwnProfile, isUsersCompanyProfile } from '../../guards'; +import { Database } from '../../database/types' +import { isOwnProfile, isUsersCompanyProfile } from '../../guards' +import { Session } from '../../types' +import { badRequestError, notFoundError } from '../../utils' export const _get = ({ db, getServerSession }: { db: Database; getServerSession: () => Promise }) => @@ -32,7 +33,7 @@ export const _get = if (isOwnProfile(user)(profile)) { return profile } - + const principal = await connection.getPrincipalByUserId(user.id) if (isUsersCompanyProfile(principal)(profile)) { return profile From fa2388e9e7bd474712ba41e34a884e893eefad8a Mon Sep 17 00:00:00 2001 From: Roy Scheeren Date: Wed, 31 Jan 2024 17:02:15 +0100 Subject: [PATCH 3/4] feat(envited.ascs.digital): get profile functionality Signed-off-by: Roy Scheeren --- .../app/companies/[slug]/page.tsx | 14 + .../common/database/queries/profiles.ts | 3 + .../common/database/queries/queries.ts | 13 +- .../common/database/queries/users.test.ts | 2 + .../common/database/queries/users.ts | 5 + .../common/database/schema.ts | 1 + .../common/guards/guards.ts | 7 +- .../common/serverActions/index.ts | 2 +- .../common/serverActions/profiles/get.test.ts | 157 +++- .../common/serverActions/profiles/get.ts | 13 +- .../common/types/types.ts | 1 + .../common/utils/utils.test.ts | 10 + .../common/utils/utils.ts | 8 + .../development/0007_calm_micromacro.sql | 7 + .../development/0008_goofy_scarlet_witch.sql | 2 + .../development/meta/0007_snapshot.json | 745 +++++++++++++++++ .../development/meta/0008_snapshot.json | 752 ++++++++++++++++++ .../drizzle/development/meta/_journal.json | 14 + .../drizzle/staging/0006_fine_maverick.sql | 8 + .../drizzle/staging/meta/0006_snapshot.json | 752 ++++++++++++++++++ .../drizzle/staging/meta/_journal.json | 7 + 21 files changed, 2482 insertions(+), 41 deletions(-) create mode 100644 apps/envited.ascs.digital/app/companies/[slug]/page.tsx create mode 100644 apps/envited.ascs.digital/drizzle/development/0007_calm_micromacro.sql create mode 100644 apps/envited.ascs.digital/drizzle/development/0008_goofy_scarlet_witch.sql create mode 100644 apps/envited.ascs.digital/drizzle/development/meta/0007_snapshot.json create mode 100644 apps/envited.ascs.digital/drizzle/development/meta/0008_snapshot.json create mode 100644 apps/envited.ascs.digital/drizzle/staging/0006_fine_maverick.sql create mode 100644 apps/envited.ascs.digital/drizzle/staging/meta/0006_snapshot.json diff --git a/apps/envited.ascs.digital/app/companies/[slug]/page.tsx b/apps/envited.ascs.digital/app/companies/[slug]/page.tsx new file mode 100644 index 00000000..ed9bff7d --- /dev/null +++ b/apps/envited.ascs.digital/app/companies/[slug]/page.tsx @@ -0,0 +1,14 @@ +import { getProfile } from '../../../common/serverActions' +import { Header } from '../../../modules/Header' + +export default async function Index({ params }: { params: { slug: string } }) { + const { slug } = params + const profile = await getProfile(slug) + + return ( + <> +
+
{JSON.stringify(profile)}
+ + ) +} diff --git a/apps/envited.ascs.digital/common/database/queries/profiles.ts b/apps/envited.ascs.digital/common/database/queries/profiles.ts index a4fb5c4a..1c449a66 100644 --- a/apps/envited.ascs.digital/common/database/queries/profiles.ts +++ b/apps/envited.ascs.digital/common/database/queries/profiles.ts @@ -18,3 +18,6 @@ export const maybeUpdatePublishedState = (db: DatabaseConnection) => async (data return db.update(profile).set({ isPublished, updatedAt: new Date() }).where(eq(profile.name, data.name)).returning() } + +export const getProfileBySlug = (db: DatabaseConnection) => async (slug: string) => + db.select().from(profile).where(eq(profile.slug, slug)) diff --git a/apps/envited.ascs.digital/common/database/queries/queries.ts b/apps/envited.ascs.digital/common/database/queries/queries.ts index c03558de..dcf92573 100644 --- a/apps/envited.ascs.digital/common/database/queries/queries.ts +++ b/apps/envited.ascs.digital/common/database/queries/queries.ts @@ -5,8 +5,15 @@ import { fromPairs, map, pipe, toPairs } from 'ramda' import { connectDb } from '../database' import * as schema from '../schema' import { fetchTables } from './common' -import { maybeUpdatePublishedState, update as updateProfile } from './profiles' -import { deleteUserById, getUserById, getUserWithProfileById, getUsersByIssuerId, insertUserTx } from './users' +import { getProfileBySlug, maybeUpdatePublishedState, update as updateProfile } from './profiles' +import { + deleteUserById, + getUserById, + getUserByIssuerId, + getUserWithProfileById, + getUsersByIssuerId, + insertUserTx, +} from './users' const queries = { deleteUserById, @@ -17,6 +24,8 @@ const queries = { insertUserTx, updateProfile, maybeUpdatePublishedState, + getProfileBySlug, + getUserByIssuerId, } export const init = diff --git a/apps/envited.ascs.digital/common/database/queries/users.test.ts b/apps/envited.ascs.digital/common/database/queries/users.test.ts index 97dad846..e4d16003 100644 --- a/apps/envited.ascs.digital/common/database/queries/users.test.ts +++ b/apps/envited.ascs.digital/common/database/queries/users.test.ts @@ -144,12 +144,14 @@ describe('common/database/users', () => { const result = await SUT.insertCompanyProfileTx(tx)({ name: 'NAME', + slug: 'name', isPublished: false, }) expect(tx.insert).toHaveBeenCalledWith(profile) expect(tx.insert().values).toHaveBeenCalledWith({ name: 'NAME', + slug: 'name', isPublished: false, createdAt: new Date(), updatedAt: new Date(), diff --git a/apps/envited.ascs.digital/common/database/queries/users.ts b/apps/envited.ascs.digital/common/database/queries/users.ts index 678c046c..a1a4acda 100644 --- a/apps/envited.ascs.digital/common/database/queries/users.ts +++ b/apps/envited.ascs.digital/common/database/queries/users.ts @@ -6,6 +6,7 @@ import postgres from 'postgres' import { isEmpty, prop, propOr } from 'ramda' import { Profile } from '../../types' +import { slugify } from '../../utils/utils' import * as schema from '../schema' import { addressType, @@ -32,6 +33,9 @@ export const getUserById = (db: DatabaseConnection) => async (id: string) => export const getUserWithProfileById = (db: DatabaseConnection) => async (id: string) => db.select().from(user).where(eq(user.id, id)).leftJoin(profile, eq(user.name, profile.name)) +export const getUserByIssuerId = (db: DatabaseConnection) => async (issuerId: string) => + db.select().from(user).where(eq(user.id, issuerId)) + export const getUsersByIssuerId = (db: DatabaseConnection) => async (issuerId: string) => db.select().from(user).where(eq(user.issuerId, issuerId)) @@ -200,6 +204,7 @@ export const _txn = await insertCompanyProfileTx(tx)({ name: credentialSubject.name, + slug: slugify(credentialSubject.name), streetAddress: credentialSubject.address.streetAddress, postalCode: credentialSubject.address.postalCode, addressLocality: credentialSubject.address.addressLocality, diff --git a/apps/envited.ascs.digital/common/database/schema.ts b/apps/envited.ascs.digital/common/database/schema.ts index 3600d475..a259c953 100644 --- a/apps/envited.ascs.digital/common/database/schema.ts +++ b/apps/envited.ascs.digital/common/database/schema.ts @@ -118,6 +118,7 @@ export const profile = pgTable('profile', { .unique() .notNull() .references(() => user.name), + slug: text('slug').unique().notNull(), description: text('description'), logo: text('logo'), streetAddress: text('street_address'), diff --git a/apps/envited.ascs.digital/common/guards/guards.ts b/apps/envited.ascs.digital/common/guards/guards.ts index 72145793..e0b9cc80 100644 --- a/apps/envited.ascs.digital/common/guards/guards.ts +++ b/apps/envited.ascs.digital/common/guards/guards.ts @@ -1,4 +1,4 @@ -import { equals, path, pathOr, prop } from 'ramda' +import { equals, pathOr, prop } from 'ramda' import { Role, Session, User } from '../../common/types/types' @@ -13,7 +13,6 @@ export const userIsIssuedByLoggedInUser = (user: User) => (session: Session) => equals(prop('issuerId')(user))(pathOr('', ['user', 'pkh'])(session)) export const isOwnProfile = (user: User) => (profile: { name: string }) => - equals(path(['profile', 'name'])(user))(prop('name')(profile)) + equals(prop('name')(user))(prop('name')(profile)) -export const isUsersCompanyProfile = (principal: User) => (profile: { name: string }) => - equals(prop('name')(principal))(prop('name')(profile)) +export const isUsersCompanyProfile = isOwnProfile diff --git a/apps/envited.ascs.digital/common/serverActions/index.ts b/apps/envited.ascs.digital/common/serverActions/index.ts index 2af1704a..d31e2d8f 100644 --- a/apps/envited.ascs.digital/common/serverActions/index.ts +++ b/apps/envited.ascs.digital/common/serverActions/index.ts @@ -1,2 +1,2 @@ export { getUserById, getUsersByIssuerId, insertUser } from './users' -export { updateProfile } from './profiles' +export { updateProfile, getProfile } from './profiles' diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts b/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts index 665415ec..aa9a869f 100644 --- a/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts +++ b/apps/envited.ascs.digital/common/serverActions/profiles/get.test.ts @@ -3,42 +3,94 @@ import * as SUT from './get' describe('serverActions/profiles/get', () => { describe('get', () => { - it('should get the profile as expected', async () => { + it('should get the own full profile as expected', async () => { // when ... we want to get the full profile for a principal user // then ... it should get the profile as expected const getServerSessionStub = jest.fn().mockResolvedValue({ user: { - id: 'USER_PKH', + id: 'USER_PRINCIPAL_PKH', role: Role.principal, }, }) const dbStub = jest.fn().mockResolvedValue({ - getProfileById: jest.fn().mockResolvedValue({ - name: 'USER_NAME', - description: 'USER_DESCRIPTION', - principalName: 'USER_PRINCIPAL_NAME', - }), - getUserById: jest.fn().mockResolvedValue({ - name: 'USER_NAME', - profile: { + getProfileBySlug: jest.fn().mockResolvedValue([ + { + name: 'USER_PRINCIPAL_NAME', + description: 'USER_DESCRIPTION', + principalName: 'USER_PRINCIPAL_NAME', + }, + ]), + getUserById: jest.fn().mockResolvedValue([ + { + name: 'USER_PRINCIPAL_NAME', + }, + ]), + getUserByIssuerId: jest.fn().mockResolvedValue([ + { + name: 'USER_PRINCIPAL_NAME', + }, + ]), + }) + + const slug = 'PROFILE_SLUG' + + const result = await SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(slug) + const db = await dbStub() + expect(result).toEqual({ + name: 'USER_PRINCIPAL_NAME', + description: 'USER_DESCRIPTION', + principalName: 'USER_PRINCIPAL_NAME', + }) + expect(getServerSessionStub).toHaveBeenCalledWith() + expect(db.getProfileBySlug).toHaveBeenCalledWith(slug) + expect(db.getUserById).toHaveBeenCalledWith('USER_PRINCIPAL_PKH') + expect(db.getUserByIssuerId).not.toHaveBeenCalled() + }) + + it('should get the full profile for a principals user as expected', async () => { + // when ... we want to get the full profile for the user of a certain principal + // then ... it should get the profile as expected + const getServerSessionStub = jest.fn().mockResolvedValue({ + user: { + id: 'USER_PKH', + role: Role.user, + }, + }) + + const dbStub = jest.fn().mockResolvedValue({ + getProfileBySlug: jest.fn().mockResolvedValue([ + { + name: 'USER_PRINCIPAL_NAME', + description: 'USER_DESCRIPTION', + principalName: 'USER_PRINCIPAL_NAME', + }, + ]), + getUserById: jest.fn().mockResolvedValue([ + { name: 'USER_NAME', }, - }), + ]), + getUserByIssuerId: jest.fn().mockResolvedValue([ + { + name: 'USER_PRINCIPAL_NAME', + }, + ]), }) - const id = 'PROFILE_ID' + const slug = 'PROFILE_SLUG' - const result = await SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(id) + const result = await SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(slug) const db = await dbStub() expect(result).toEqual({ - name: 'USER_NAME', + name: 'USER_PRINCIPAL_NAME', description: 'USER_DESCRIPTION', principalName: 'USER_PRINCIPAL_NAME', }) expect(getServerSessionStub).toHaveBeenCalledWith() - expect(db.getProfileById).toHaveBeenCalledWith(id) + expect(db.getProfileBySlug).toHaveBeenCalledWith(slug) expect(db.getUserById).toHaveBeenCalledWith('USER_PKH') + expect(db.getUserByIssuerId).toHaveBeenCalled() }) it('should return a limited profile when there is no session', async () => { @@ -47,27 +99,78 @@ describe('serverActions/profiles/get', () => { const getServerSessionStub = jest.fn().mockResolvedValue(null) const dbStub = jest.fn().mockResolvedValue({ - getProfileById: jest.fn().mockResolvedValue({ - name: 'USER_NAME', - description: 'USER_DESCRIPTION', - principalName: 'USER_PRINCIPAL_NAME', - }), - getUserById: jest.fn().mockResolvedValue({ - name: 'USER_NAME', - profile: { + getProfileBySlug: jest.fn().mockResolvedValue([ + { + name: 'USER_NAME', + description: 'USER_DESCRIPTION', + principalName: 'USER_PRINCIPAL_NAME', + }, + ]), + getUserById: jest.fn().mockResolvedValue([ + { name: 'USER_NAME', + profile: { + name: 'USER_NAME', + }, }, - }), + ]), }) - const id = 'PROFILE_ID' - - const result = await SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(id) + const slug = 'PROFILE_SLUG' + const result = await SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(slug) + const db = await dbStub() expect(result).toEqual({ name: 'USER_NAME', description: 'USER_DESCRIPTION', }) + expect(getServerSessionStub).toHaveBeenCalledWith() + expect(db.getProfileBySlug).toHaveBeenCalledWith(slug) + expect(db.getUserById).not.toHaveBeenCalled() + }) + + it('should throw an error when the profile id is missing', async () => { + // when ... we want to get a profile but the id is missing + // then ... it should throw an error + const getServerSessionStub = jest.fn().mockResolvedValue([ + { + user: { + id: 'USER_PRINCIPAL_PKH', + role: Role.principal, + }, + }, + ]) + + const dbStub = jest.fn().mockResolvedValue({}) + + const slug = '' + + expect.assertions(3) + await expect(() => SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(slug)).rejects.toThrow() + expect(getServerSessionStub).not.toHaveBeenCalledWith() + expect(dbStub).not.toHaveBeenCalled() }) }) + + it('should throw an error when the profile is not found', async () => { + // when ... we want to get a non existant profile + // then ... it should throw an error + const getServerSessionStub = jest.fn().mockResolvedValue({ + user: { + id: 'USER_PRINCIPAL_PKH', + role: Role.principal, + }, + }) + + const dbStub = jest.fn().mockResolvedValue({ + getProfileBySlug: jest.fn().mockResolvedValue(null), + }) + + const slug = 'NON_EXISTANT_PROFILE_SLUG' + const db = await dbStub() + await expect(() => SUT._get({ db: dbStub, getServerSession: getServerSessionStub })(slug)).rejects.toThrow() + expect(getServerSessionStub).toHaveBeenCalledWith() + expect(dbStub).toHaveBeenCalledWith() + expect(db.getProfileBySlug).toHaveBeenCalledWith(slug) + }) }) diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/get.ts b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts index 3e289b18..404141bd 100644 --- a/apps/envited.ascs.digital/common/serverActions/profiles/get.ts +++ b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts @@ -1,6 +1,5 @@ 'use server' -import { error } from 'console' import { isEmpty, isNil, omit } from 'ramda' import { getServerSession } from '../../auth' @@ -9,32 +8,32 @@ import { db } from '../../database/queries' import { Database } from '../../database/types' import { isOwnProfile, isUsersCompanyProfile } from '../../guards' import { Session } from '../../types' -import { badRequestError, notFoundError } from '../../utils' +import { badRequestError, error, notFoundError } from '../../utils' export const _get = ({ db, getServerSession }: { db: Database; getServerSession: () => Promise }) => - async (id: string) => { + async (slug: string) => { try { - if (isNil(id) || isEmpty(id)) { + if (isNil(slug) || isEmpty(slug)) { throw badRequestError('Missing profile id') } const session = await getServerSession() const connection = await db() - const profile = await connection.getProfileById(id) + const [profile] = await connection.getProfileBySlug(slug) if (isNil(profile) || isEmpty(profile)) { throw notFoundError() } if (!isNil(session)) { - const user = await connection.getUserById(session.user.id) + const [user] = await connection.getUserById(session.user.id) if (isOwnProfile(user)(profile)) { return profile } - const principal = await connection.getPrincipalByUserId(user.id) + const [principal] = await connection.getUserByIssuerId(user.issuerId) if (isUsersCompanyProfile(principal)(profile)) { return profile } diff --git a/apps/envited.ascs.digital/common/types/types.ts b/apps/envited.ascs.digital/common/types/types.ts index bfc89916..e61df8be 100644 --- a/apps/envited.ascs.digital/common/types/types.ts +++ b/apps/envited.ascs.digital/common/types/types.ts @@ -76,6 +76,7 @@ export interface User { export interface Profile { id?: string name: string + slug: string description?: string | null logo?: string | null streetAddress?: string | null diff --git a/apps/envited.ascs.digital/common/utils/utils.test.ts b/apps/envited.ascs.digital/common/utils/utils.test.ts index 3577d1de..812c1f23 100644 --- a/apps/envited.ascs.digital/common/utils/utils.test.ts +++ b/apps/envited.ascs.digital/common/utils/utils.test.ts @@ -31,4 +31,14 @@ describe('common/utils', () => { expect(result).toEqual('AscsUser') }) }) + + describe('slugify', () => { + it('should create a slug of the string as expected', () => { + // when ... we want to create a slug of the string + // then ... we should get the slug as expected + const result = SUT.slugify('This is a test') + + expect(result).toEqual('this-is-a-test') + }) + }) }) diff --git a/apps/envited.ascs.digital/common/utils/utils.ts b/apps/envited.ascs.digital/common/utils/utils.ts index 97bf7d82..8dbf172e 100644 --- a/apps/envited.ascs.digital/common/utils/utils.ts +++ b/apps/envited.ascs.digital/common/utils/utils.ts @@ -5,3 +5,11 @@ export const extractIdFromCredential = pathOr('', ['credentialSubject', 'id']) export const extractIssuerIdFromCredential = pathOr('', ['issuer', 'id']) export const extractTypeFromCredential = pathOr('', ['credentialSubject', 'type']) + +export const slugify = (string: string) => + string + .toLowerCase() + .trim() + .replace(/[^\w\s-]/g, '') + .replace(/[\s_-]+/g, '-') + .replace(/^-+|-+$/g, '') diff --git a/apps/envited.ascs.digital/drizzle/development/0007_calm_micromacro.sql b/apps/envited.ascs.digital/drizzle/development/0007_calm_micromacro.sql new file mode 100644 index 00000000..708dbc3c --- /dev/null +++ b/apps/envited.ascs.digital/drizzle/development/0007_calm_micromacro.sql @@ -0,0 +1,7 @@ +ALTER TABLE "profile" RENAME COLUMN "first_name" TO "sales_name";--> statement-breakpoint +ALTER TABLE "profile" RENAME COLUMN "phone" TO "sales_phone";--> statement-breakpoint +ALTER TABLE "profile" RENAME COLUMN "email" TO "sales_email";--> statement-breakpoint +ALTER TABLE "profile" RENAME COLUMN "last_name" TO "principal_name";--> statement-breakpoint +ALTER TABLE "profile" ADD COLUMN "slug" text;--> statement-breakpoint +ALTER TABLE "profile" ADD COLUMN "principal_phone" text;--> statement-breakpoint +ALTER TABLE "profile" ADD COLUMN "principal_email" text; \ No newline at end of file diff --git a/apps/envited.ascs.digital/drizzle/development/0008_goofy_scarlet_witch.sql b/apps/envited.ascs.digital/drizzle/development/0008_goofy_scarlet_witch.sql new file mode 100644 index 00000000..306aa3ab --- /dev/null +++ b/apps/envited.ascs.digital/drizzle/development/0008_goofy_scarlet_witch.sql @@ -0,0 +1,2 @@ +ALTER TABLE "profile" ALTER COLUMN "slug" SET NOT NULL;--> statement-breakpoint +ALTER TABLE "profile" ADD CONSTRAINT "profile_slug_unique" UNIQUE("slug"); \ No newline at end of file diff --git a/apps/envited.ascs.digital/drizzle/development/meta/0007_snapshot.json b/apps/envited.ascs.digital/drizzle/development/meta/0007_snapshot.json new file mode 100644 index 00000000..f1d5b7c5 --- /dev/null +++ b/apps/envited.ascs.digital/drizzle/development/meta/0007_snapshot.json @@ -0,0 +1,745 @@ +{ + "id": "9e388076-f6fb-406c-a10e-d368f8cdd15c", + "prevId": "7c39d3af-9803-4f74-b950-55a3f248f0ab", + "version": "5", + "dialect": "pg", + "tables": { + "addressType": { + "name": "addressType", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "addressType_name_unique": { + "name": "addressType_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "companyCategory": { + "name": "companyCategory", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "companyCategory_id_unique": { + "name": "companyCategory_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + }, + "companyCategory_name_unique": { + "name": "companyCategory_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "credentialType": { + "name": "credentialType", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "issuer": { + "name": "issuer", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "issuer_id_unique": { + "name": "issuer_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + } + }, + "profile": { + "name": "profile", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_locality": { + "name": "address_locality", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_name": { + "name": "sales_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_phone": { + "name": "sales_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_email": { + "name": "sales_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_name": { + "name": "principal_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_phone": { + "name": "principal_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_email": { + "name": "principal_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "website": { + "name": "website", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "offerings": { + "name": "offerings", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_published": { + "name": "is_published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "profile_name_user_name_fk": { + "name": "profile_name_user_name_fk", + "tableFrom": "profile", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "name" + ], + "columnsTo": [ + "name" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "profile_name_unique": { + "name": "profile_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "profilesToCompanyCategories": { + "name": "profilesToCompanyCategories", + "schema": "", + "columns": { + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "company_category_id": { + "name": "company_category_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profilesToCompanyCategories_profile_id_profile_id_fk": { + "name": "profilesToCompanyCategories_profile_id_profile_id_fk", + "tableFrom": "profilesToCompanyCategories", + "tableTo": "profile", + "schemaTo": "public", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "profilesToCompanyCategories_company_category_id_companyCategory_id_fk": { + "name": "profilesToCompanyCategories_company_category_id_companyCategory_id_fk", + "tableFrom": "profilesToCompanyCategories", + "tableTo": "companyCategory", + "schemaTo": "public", + "columnsFrom": [ + "company_category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "role": { + "name": "role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "role_id_unique": { + "name": "role_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + } + }, + "user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_ascs_member": { + "name": "is_ascs_member", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_envited_member": { + "name": "is_envited_member", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_locality": { + "name": "address_locality", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vat_id": { + "name": "vat_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "privacy_policy_accepted": { + "name": "privacy_policy_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "articles_of_association_accepted": { + "name": "articles_of_association_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contribution_rules_accepted": { + "name": "contribution_rules_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issuer_id": { + "name": "issuer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address_type_id": { + "name": "address_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "issuance_date": { + "name": "issuance_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expiration_date": { + "name": "expiration_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_issuer_id_issuer_id_fk": { + "name": "user_issuer_id_issuer_id_fk", + "tableFrom": "user", + "tableTo": "issuer", + "schemaTo": "public", + "columnsFrom": [ + "issuer_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "user_address_type_id_addressType_id_fk": { + "name": "user_address_type_id_addressType_id_fk", + "tableFrom": "user", + "tableTo": "addressType", + "schemaTo": "public", + "columnsFrom": [ + "address_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_id_unique": { + "name": "user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + }, + "user_name_unique": { + "name": "user_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "usersToCredentialTypes": { + "name": "usersToCredentialTypes", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credential_type_id": { + "name": "credential_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "usersToCredentialTypes_user_id_user_id_fk": { + "name": "usersToCredentialTypes_user_id_user_id_fk", + "tableFrom": "usersToCredentialTypes", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "usersToCredentialTypes_credential_type_id_credentialType_id_fk": { + "name": "usersToCredentialTypes_credential_type_id_credentialType_id_fk", + "tableFrom": "usersToCredentialTypes", + "tableTo": "credentialType", + "schemaTo": "public", + "columnsFrom": [ + "credential_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "usersToRoles": { + "name": "usersToRoles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "usersToRoles_user_id_user_id_fk": { + "name": "usersToRoles_user_id_user_id_fk", + "tableFrom": "usersToRoles", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "usersToRoles_role_id_role_id_fk": { + "name": "usersToRoles_role_id_role_id_fk", + "tableFrom": "usersToRoles", + "tableTo": "role", + "schemaTo": "public", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/envited.ascs.digital/drizzle/development/meta/0008_snapshot.json b/apps/envited.ascs.digital/drizzle/development/meta/0008_snapshot.json new file mode 100644 index 00000000..1bf86170 --- /dev/null +++ b/apps/envited.ascs.digital/drizzle/development/meta/0008_snapshot.json @@ -0,0 +1,752 @@ +{ + "id": "5bc1029f-3da8-4d61-84b1-70356c60f4f7", + "prevId": "9e388076-f6fb-406c-a10e-d368f8cdd15c", + "version": "5", + "dialect": "pg", + "tables": { + "addressType": { + "name": "addressType", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "addressType_name_unique": { + "name": "addressType_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "companyCategory": { + "name": "companyCategory", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "companyCategory_id_unique": { + "name": "companyCategory_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + }, + "companyCategory_name_unique": { + "name": "companyCategory_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "credentialType": { + "name": "credentialType", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "issuer": { + "name": "issuer", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "issuer_id_unique": { + "name": "issuer_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + } + }, + "profile": { + "name": "profile", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_locality": { + "name": "address_locality", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_name": { + "name": "sales_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_phone": { + "name": "sales_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_email": { + "name": "sales_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_name": { + "name": "principal_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_phone": { + "name": "principal_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_email": { + "name": "principal_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "website": { + "name": "website", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "offerings": { + "name": "offerings", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_published": { + "name": "is_published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "profile_name_user_name_fk": { + "name": "profile_name_user_name_fk", + "tableFrom": "profile", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "name" + ], + "columnsTo": [ + "name" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "profile_name_unique": { + "name": "profile_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + }, + "profile_slug_unique": { + "name": "profile_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + } + }, + "profilesToCompanyCategories": { + "name": "profilesToCompanyCategories", + "schema": "", + "columns": { + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "company_category_id": { + "name": "company_category_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profilesToCompanyCategories_profile_id_profile_id_fk": { + "name": "profilesToCompanyCategories_profile_id_profile_id_fk", + "tableFrom": "profilesToCompanyCategories", + "tableTo": "profile", + "schemaTo": "public", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "profilesToCompanyCategories_company_category_id_companyCategory_id_fk": { + "name": "profilesToCompanyCategories_company_category_id_companyCategory_id_fk", + "tableFrom": "profilesToCompanyCategories", + "tableTo": "companyCategory", + "schemaTo": "public", + "columnsFrom": [ + "company_category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "role": { + "name": "role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "role_id_unique": { + "name": "role_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + } + }, + "user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_ascs_member": { + "name": "is_ascs_member", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_envited_member": { + "name": "is_envited_member", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_locality": { + "name": "address_locality", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vat_id": { + "name": "vat_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "privacy_policy_accepted": { + "name": "privacy_policy_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "articles_of_association_accepted": { + "name": "articles_of_association_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contribution_rules_accepted": { + "name": "contribution_rules_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issuer_id": { + "name": "issuer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address_type_id": { + "name": "address_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "issuance_date": { + "name": "issuance_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expiration_date": { + "name": "expiration_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_issuer_id_issuer_id_fk": { + "name": "user_issuer_id_issuer_id_fk", + "tableFrom": "user", + "tableTo": "issuer", + "schemaTo": "public", + "columnsFrom": [ + "issuer_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "user_address_type_id_addressType_id_fk": { + "name": "user_address_type_id_addressType_id_fk", + "tableFrom": "user", + "tableTo": "addressType", + "schemaTo": "public", + "columnsFrom": [ + "address_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_id_unique": { + "name": "user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + }, + "user_name_unique": { + "name": "user_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "usersToCredentialTypes": { + "name": "usersToCredentialTypes", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credential_type_id": { + "name": "credential_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "usersToCredentialTypes_user_id_user_id_fk": { + "name": "usersToCredentialTypes_user_id_user_id_fk", + "tableFrom": "usersToCredentialTypes", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "usersToCredentialTypes_credential_type_id_credentialType_id_fk": { + "name": "usersToCredentialTypes_credential_type_id_credentialType_id_fk", + "tableFrom": "usersToCredentialTypes", + "tableTo": "credentialType", + "schemaTo": "public", + "columnsFrom": [ + "credential_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "usersToRoles": { + "name": "usersToRoles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "usersToRoles_user_id_user_id_fk": { + "name": "usersToRoles_user_id_user_id_fk", + "tableFrom": "usersToRoles", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "usersToRoles_role_id_role_id_fk": { + "name": "usersToRoles_role_id_role_id_fk", + "tableFrom": "usersToRoles", + "tableTo": "role", + "schemaTo": "public", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/envited.ascs.digital/drizzle/development/meta/_journal.json b/apps/envited.ascs.digital/drizzle/development/meta/_journal.json index dc0598fe..65c61390 100644 --- a/apps/envited.ascs.digital/drizzle/development/meta/_journal.json +++ b/apps/envited.ascs.digital/drizzle/development/meta/_journal.json @@ -50,6 +50,20 @@ "when": 1706625704993, "tag": "0006_complete_caretaker", "breakpoints": true + }, + { + "idx": 7, + "version": "5", + "when": 1706714023800, + "tag": "0007_calm_micromacro", + "breakpoints": true + }, + { + "idx": 8, + "version": "5", + "when": 1706714069769, + "tag": "0008_goofy_scarlet_witch", + "breakpoints": true } ] } \ No newline at end of file diff --git a/apps/envited.ascs.digital/drizzle/staging/0006_fine_maverick.sql b/apps/envited.ascs.digital/drizzle/staging/0006_fine_maverick.sql new file mode 100644 index 00000000..65cc9338 --- /dev/null +++ b/apps/envited.ascs.digital/drizzle/staging/0006_fine_maverick.sql @@ -0,0 +1,8 @@ +ALTER TABLE "profile" RENAME COLUMN "first_name" TO "sales_name";--> statement-breakpoint +ALTER TABLE "profile" RENAME COLUMN "phone" TO "sales_phone";--> statement-breakpoint +ALTER TABLE "profile" RENAME COLUMN "email" TO "sales_email";--> statement-breakpoint +ALTER TABLE "profile" RENAME COLUMN "last_name" TO "principal_name";--> statement-breakpoint +ALTER TABLE "profile" ADD COLUMN "slug" text NOT NULL;--> statement-breakpoint +ALTER TABLE "profile" ADD COLUMN "principal_phone" text;--> statement-breakpoint +ALTER TABLE "profile" ADD COLUMN "principal_email" text;--> statement-breakpoint +ALTER TABLE "profile" ADD CONSTRAINT "profile_slug_unique" UNIQUE("slug"); \ No newline at end of file diff --git a/apps/envited.ascs.digital/drizzle/staging/meta/0006_snapshot.json b/apps/envited.ascs.digital/drizzle/staging/meta/0006_snapshot.json new file mode 100644 index 00000000..f23a8d56 --- /dev/null +++ b/apps/envited.ascs.digital/drizzle/staging/meta/0006_snapshot.json @@ -0,0 +1,752 @@ +{ + "id": "7751b268-6c28-4ff5-a7cb-a2c59831b157", + "prevId": "557a5fc8-66db-4aa8-bc60-1c6600b02847", + "version": "5", + "dialect": "pg", + "tables": { + "addressType": { + "name": "addressType", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "addressType_name_unique": { + "name": "addressType_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "companyCategory": { + "name": "companyCategory", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "companyCategory_id_unique": { + "name": "companyCategory_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + }, + "companyCategory_name_unique": { + "name": "companyCategory_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "credentialType": { + "name": "credentialType", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "issuer": { + "name": "issuer", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "issuer_id_unique": { + "name": "issuer_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + } + }, + "profile": { + "name": "profile", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_locality": { + "name": "address_locality", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_name": { + "name": "sales_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_phone": { + "name": "sales_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sales_email": { + "name": "sales_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_name": { + "name": "principal_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_phone": { + "name": "principal_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "principal_email": { + "name": "principal_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "website": { + "name": "website", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "offerings": { + "name": "offerings", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_published": { + "name": "is_published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "profile_name_user_name_fk": { + "name": "profile_name_user_name_fk", + "tableFrom": "profile", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "name" + ], + "columnsTo": [ + "name" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "profile_name_unique": { + "name": "profile_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + }, + "profile_slug_unique": { + "name": "profile_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + } + }, + "profilesToCompanyCategories": { + "name": "profilesToCompanyCategories", + "schema": "", + "columns": { + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "company_category_id": { + "name": "company_category_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "profilesToCompanyCategories_profile_id_profile_id_fk": { + "name": "profilesToCompanyCategories_profile_id_profile_id_fk", + "tableFrom": "profilesToCompanyCategories", + "tableTo": "profile", + "schemaTo": "public", + "columnsFrom": [ + "profile_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "profilesToCompanyCategories_company_category_id_companyCategory_id_fk": { + "name": "profilesToCompanyCategories_company_category_id_companyCategory_id_fk", + "tableFrom": "profilesToCompanyCategories", + "tableTo": "companyCategory", + "schemaTo": "public", + "columnsFrom": [ + "company_category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "role": { + "name": "role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "role_id_unique": { + "name": "role_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + } + }, + "user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_ascs_member": { + "name": "is_ascs_member", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "is_envited_member": { + "name": "is_envited_member", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_locality": { + "name": "address_locality", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "address_country": { + "name": "address_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vat_id": { + "name": "vat_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "privacy_policy_accepted": { + "name": "privacy_policy_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "articles_of_association_accepted": { + "name": "articles_of_association_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contribution_rules_accepted": { + "name": "contribution_rules_accepted", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "issuer_id": { + "name": "issuer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address_type_id": { + "name": "address_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "issuance_date": { + "name": "issuance_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expiration_date": { + "name": "expiration_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_issuer_id_issuer_id_fk": { + "name": "user_issuer_id_issuer_id_fk", + "tableFrom": "user", + "tableTo": "issuer", + "schemaTo": "public", + "columnsFrom": [ + "issuer_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "user_address_type_id_addressType_id_fk": { + "name": "user_address_type_id_addressType_id_fk", + "tableFrom": "user", + "tableTo": "addressType", + "schemaTo": "public", + "columnsFrom": [ + "address_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_id_unique": { + "name": "user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + }, + "user_name_unique": { + "name": "user_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "usersToCredentialTypes": { + "name": "usersToCredentialTypes", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credential_type_id": { + "name": "credential_type_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "usersToCredentialTypes_user_id_user_id_fk": { + "name": "usersToCredentialTypes_user_id_user_id_fk", + "tableFrom": "usersToCredentialTypes", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "usersToCredentialTypes_credential_type_id_credentialType_id_fk": { + "name": "usersToCredentialTypes_credential_type_id_credentialType_id_fk", + "tableFrom": "usersToCredentialTypes", + "tableTo": "credentialType", + "schemaTo": "public", + "columnsFrom": [ + "credential_type_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "usersToRoles": { + "name": "usersToRoles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "usersToRoles_user_id_user_id_fk": { + "name": "usersToRoles_user_id_user_id_fk", + "tableFrom": "usersToRoles", + "tableTo": "user", + "schemaTo": "public", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "usersToRoles_role_id_role_id_fk": { + "name": "usersToRoles_role_id_role_id_fk", + "tableFrom": "usersToRoles", + "tableTo": "role", + "schemaTo": "public", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json b/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json index a8d95c24..f4684af5 100644 --- a/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json +++ b/apps/envited.ascs.digital/drizzle/staging/meta/_journal.json @@ -43,6 +43,13 @@ "when": 1706625722525, "tag": "0005_sour_king_cobra", "breakpoints": true + }, + { + "idx": 6, + "version": "5", + "when": 1706716757110, + "tag": "0006_fine_maverick", + "breakpoints": true } ] } \ No newline at end of file From ffa73ecd0f0d937786b84b77835a15bdbbd8c0f8 Mon Sep 17 00:00:00 2001 From: Roy Scheeren Date: Wed, 31 Jan 2024 18:12:42 +0100 Subject: [PATCH 4/4] refactor(envited.ascs.digital): slug Signed-off-by: Roy Scheeren --- apps/envited.ascs.digital/app/companies/[slug]/page.tsx | 3 +-- apps/envited.ascs.digital/common/database/queries/users.ts | 2 +- apps/envited.ascs.digital/common/serverActions/profiles/get.ts | 2 +- apps/envited.ascs.digital/common/utils/index.ts | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/envited.ascs.digital/app/companies/[slug]/page.tsx b/apps/envited.ascs.digital/app/companies/[slug]/page.tsx index ed9bff7d..366c8286 100644 --- a/apps/envited.ascs.digital/app/companies/[slug]/page.tsx +++ b/apps/envited.ascs.digital/app/companies/[slug]/page.tsx @@ -1,8 +1,7 @@ import { getProfile } from '../../../common/serverActions' import { Header } from '../../../modules/Header' -export default async function Index({ params }: { params: { slug: string } }) { - const { slug } = params +export default async function Index({ params: { slug } }: { params: { slug: string } }) { const profile = await getProfile(slug) return ( diff --git a/apps/envited.ascs.digital/common/database/queries/users.ts b/apps/envited.ascs.digital/common/database/queries/users.ts index a1a4acda..76427fc2 100644 --- a/apps/envited.ascs.digital/common/database/queries/users.ts +++ b/apps/envited.ascs.digital/common/database/queries/users.ts @@ -6,7 +6,7 @@ import postgres from 'postgres' import { isEmpty, prop, propOr } from 'ramda' import { Profile } from '../../types' -import { slugify } from '../../utils/utils' +import { slugify } from '../../utils' import * as schema from '../schema' import { addressType, diff --git a/apps/envited.ascs.digital/common/serverActions/profiles/get.ts b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts index 404141bd..f3d1fadd 100644 --- a/apps/envited.ascs.digital/common/serverActions/profiles/get.ts +++ b/apps/envited.ascs.digital/common/serverActions/profiles/get.ts @@ -15,7 +15,7 @@ export const _get = async (slug: string) => { try { if (isNil(slug) || isEmpty(slug)) { - throw badRequestError('Missing profile id') + throw badRequestError('Missing slug') } const session = await getServerSession() diff --git a/apps/envited.ascs.digital/common/utils/index.ts b/apps/envited.ascs.digital/common/utils/index.ts index 8c66e2c6..9733fb64 100644 --- a/apps/envited.ascs.digital/common/utils/index.ts +++ b/apps/envited.ascs.digital/common/utils/index.ts @@ -8,4 +8,4 @@ export { error, } from './errors' -export { extractIdFromCredential, extractIssuerIdFromCredential, extractTypeFromCredential } from './utils' +export { extractIdFromCredential, extractIssuerIdFromCredential, extractTypeFromCredential, slugify } from './utils'